webpack SpiltChunks实践指南
# 前言
在一次项目升级时由于新增了比较多的功能引入了比较多的插件,面对诸多插件的暴打,突然本文的主角突然出现,对着我一顿 buf 加特猛如虎。事后对 SplitChunks 心怀好感, 特意总结实践以表心意。
SplitChunks 从字面可得知是用来分割块的,作为 webpack 的性能优化利器,其主要作用是提取公共代码,防止代码被重复打包,拆分过大的 js 文件,合并零散的 js 文件。
webpack 4 移除 CommonsChunkPlugin,取而代之的是两个新的配置项(optimization.splitChunks 和 optimization.runtimeChunk)。
# 配置参数
chunks:决定要提取哪些模块。可选值有:async,initial 和 all。
async: 默认值。只提取异步加载的模块打包到一个文件中。
- 异步加载的模块:通过 import('xxx')或 require(['xxx'],() =>{}) 加载的模块。
all:提取同步加载和异步加载模块,如果 xxx 在项目中异步加载了,也同步加载了,那么 xxx 这个模块会被提取两次,分别打包到不同的文件中。
- 同步加载的模块:通过 import xxx 或 require('xxx') 加载的模块。
initial: 不管异步加载还是同步加载的模块都提取出来,打包到一个文件中。
minSize:默认值 30000byte。规定被提取的模块在压缩前的大小最小值,只有超过规定尺寸才会被提取。
maxSize:默认值 0byte。把提取出来的模块打包生成的文件大小不能超过 maxSize 值,如果超过了,要对其进行分割并打包生成新的文件。
- 值为 0 时表示不限制大小。
minChunks:默认值 1。表示要被提取的模块最小被引用次数,引用次数超过或等于 minChunks 值,才能被提取(译注:保证代码块复用性,默认配置的策略是不需要多次引用也可以被分割)。
maxInitialRequests:默认值 4。打包后的入口文件加载时,还能同时加载 js 文件的数量(包括入口文件)。
maxAsyncRequests:默认值 6。按需加载时候最大的并行请求数。
automaticNameDelimiter:默认值 ~。指定用于生成名称的分隔符。(webpack 将使用 chunk 的来源和名称生成名称。例如 vendors~main.js)
enforceSizeThreshold:默认值 50000byte。强制执行拆分的体积阈值和其他限制(minRemainingSize,maxAsyncRequests,maxInitialRequests)将被忽略。
- 注意 splitChunks.minRemainingSize 仅在剩余单个 chunk 时生效。
minRemainingSize:默认值 0,。在 webpack 5 中引入了 splitChunks.minRemainingSize 选项,通过确保拆分后剩余的最小 chunk 体积超过限制来避免大小为零的模块。 'development' 模式 中默认为 0。对于其他情况,splitChunks.minRemainingSize 默认为 splitChunks.minSize 的值,因此除需要深度控制的极少数情况外,不需要手动指定它。
defaultSizeTypes:默认值 ['javascript', 'unknown']。设置当数字用于大小时使用的大小类型。
name:打包的 chunks 的名字,字符串或者函数(函数可以根据条件自定义名字)
cacheGroups:核心重点,配置提取模块的方案。里面每一项代表一个提取模块的方案。若 cacheGroups 每项中有,就按配置的,没有就使用外面配置的。下面是 cacheGroups 每项中特有的选项,其余选项和外面一致。
test: 用于控制哪些模块被这个缓存组匹配到。原封不动传递出去的话,它默认会选择所有的模块。可以传递的值类型:RegExp、String 和 Function
priority:缓存组打包的优先级,数字越大提取代码的优先级越高。
reuseExistingChunk:选填 true/false。为 true 时,如果当前要提取的模块,在已经在打包生成的 js 文件中存在,则将重用该模块,而不是把当前要提取的模块打包生成新的 js 文件。
enforce:选填 true/false。为 true 时,忽略 minSize,minChunks,maxAsyncRequests 和 maxInitialRequests 外面选项
注意:模块请求次数与模块大小的优先级: maxInitialRequests / maxAsyncRequests < maxSize < minSize
模板如下:
// vue.config.js
{
configureWebpack: (config) => {
config.optimization = {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 6,
maxInitialRequests: 4,
automaticNameDelimiter: '~',
cacheGroups: {
common: {
name: 'chunk-common',
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: -20,
reuseExistingChunk: true,
enforce: true,
},
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
chunks: 'initial',
priority: -10,
},
vant: {
name: 'chunk-vant',
test: /[\\/]node_modules[\\/]vant[\\/]/,
chunks: 'all',
priority: 0,
},
},
},
};
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40