webpack 之 高级概念篇

171 阅读4分钟

「本文正在参与技术专题征文Node.js进阶之路,点击查看详情

一、 打包分析,Preloading, Prefetching

(1)可以通过一些打包文件分析自己的打包效率,从而有针对性的优化。

分析工具参考:github.com/webpack/ana… webpack.docschina.org/guides/code…

image.png

(2)查看代码使用覆盖率

在控制面板,使用ctrl+shift+p,搜索Coverage或者覆盖范围,可以查看代码覆盖使用率。

image.png

如图示例:

image.png

目前推荐将代码写成多模块,然后异步加载方式,这样代码使用覆盖率高,能较好提高性能,这比使用缓存的方法提升性能要好很多。

(3)使用prefetch和preload优化

参考:blog.csdn.net/hjc256/arti… 我们要通过一种称作Magic Comment(魔法注释)的方式,让Webpack输出"resource hint(资源提示)",来告知浏览器提前加载。

/* webpackPrefetch: true */

image.png

实际上这样做,Webpack替我们在head内添加了这样一行:

<link rel="prefetch" href="index.js" as="script">

preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。

preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。

preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。

浏览器支持程度不同。

感觉用prefetch会好一些。

二、 CSS 文件的代码分割、压缩

1. output中的fileName和chunkFileName

fileName和chunkFileName会被直接引入到html中的走filename,其他chunk使用chunkFilename配置项

  • filename: 入口打包出的文件名
  • chunkFileName: 打包出的chunk名字

image.png

没有插件之前,webpack默认会将css打包到js中

2. css代码分割插件:mini-css-extranct-plugin

  • 缺点:暂时不支持HRM,因此适合在线上打包。

image.png

2.1 安装 -> 使用:

1)在webpack.prod.js中配置plugin 2)更改loader,在webpack.prod.js中,配置style-loader改为MiniCssExtratPlugin.loader。

如果不起作用,考虑css是否被tree shaking。 packsge.json修改 sideEffects:["*.css"]  //对于css文件不做tree shaking

image.png

2.2 根据不同的入口代码分割

image.png

3、压缩css文件插件: optimize-css-webpack-plugin

三、 Webpack 与浏览器缓存( Caching )

当我们改变了业务代码后并打包后,生成的打包文件名称并未发生改变,浏览器会用之前的缓存。

所以我们需要对打包文件名称进行配置。

hash

如果都使用hash的话,因为这是工程级别的,即每次修改任何一个文件,所有文件名的hash至都将改变。

所以一旦修改了任何一个文件,整个项目的文件缓存都将失效

chunkhash

chunkhash根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。

在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,接着我们采用chunkhash的方式生成哈希值。

那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。

contenthash:

contenthash是针对文件内容级别的,只有你自己模块的内容变了,那么hash值才改变,所以我们可以通过contenthash解决上诉问题

output: {
    filename: '[name].[contenthash].js', // 这里就的conenthash会根据你的代码不同就生成不同的hash,
    chunkFilename: '[name].[contenthash].js'
}

旧版本的webpack的处理

旧版本的webpack可能无论是否有改变内容去打包那个哈希值都会不同的,需要加个配置项:

optimization: {
    runtimeChunk: {
        name: 'runtime'
    }
}

四、 Shimming 的作用

shimming作用:解决webpack打包的兼容性问题

如果你想这样直接使用jQuery$

image.png

如上图的直接用法,由于没有引入jQuery 会找不到 $ 所以要处理下

使用shimming垫片

模块打包,变量隔离;

使用webpack自带的ProvidePlugin,当发现模块中使用$字符,会自动引入jQuery模块

image.png

new webpack.ProvidePlugin({ 
    $: 'jquery', 
    _join: ['lodash', 'join']
}) 

按上图的配置就不需要每次使用$的时候引入了,这个插件就成为垫片

模块里面的this指向模块本身

如果想JS模块的this指向window,使用imports-loader

use: [
    {loader: 'babel-loader'}, 
    {loader: 'imports-loader?this=>window'}
]

image.png

五、 环境变量的使用方法

使用全局变量决定打包方式

webpack.common.js

// webpack.common.js 

module.exports = (env) => {
    if(env&&env.production) {
        return merge(commonconfig,proConfig) 
    } else { 
        return merge(commonconfig,devConfig)
    } 
}

image.png

package.json

// package.json
"build":"webpack --env.production --config ./build/webpack.prod.js"

webpack --env.production=true 默认就是true

image.png

六、如何进行多页面打包配置?

1)配置多个入口文件

entry:{
    main: './src/index.js’,
    list: './src/list.js',
    detail: './src/list.js'
}

2)借助HtmlwebpackPlugin插件创建对应html

html-webpack-plugin 官方文档:github.com/jantimon/ht…

image.png

如何动态借助 HtmlwebpackPlugin 插件创建对应html?

如上图所示,

配置多个entry, 需要new多个htmlWebpackPlugin

配置template, filename, 对应的chunks

会有重读类似的配置出现多次

我们可以使用Node封装一个函数来实现

image.png