一、前言
webpack 4.0 使用 optimization.splitChunks.cacheGroups
配置项来进行包的拆分,其实默认情况下,webpack是会自动帮我们分割的,但是有时候我们可能也需要自定义配置,下面来说下我对这个配置项的理解,如有错误,烦请指出
二、配置项说明
- cacheGroups
- 用这个配置项来自定义生成的文件
- test
- 限制范围,可以是正则,匹配文件夹或文件
- name
- 生成的文件名
- priority
- 优先级,当有chunks满足多个分组条件的时候,优先选择优先级高的
- minSize
- 分出来的包最小尺寸必须大于此值,默认30000B
- minChunks
- 表示分离前被引用次数,默认为1
- maxInitialRequests
- 最大初始化加载次数,一个入口文件可以并行加载的最大文件数量,默认1
- maxAsyncRequests
- 最大按需加载次数,最大异步加载次数,默认1
- enforce: true
- 优先处理,这一项好像和priority有些重叠了
- reuseExistingChunk:true
- 表示可以使用已经存在的块,即如果满足条件的块已经存在就是用己有的的,不再创建一个新的块
- chunks 值为”initial”, “async”(默认) 或 “all”
- initial 入口chunk,对于异步导入的文件不处理
- async 异步chunk,只对异步导入的文件处理
- all 全部chunk
12.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20runtimeChunk: {
name: 'manifest'
/* 管理被分出来的包,runtime 指的是 webpack 的运行环境(具体作用就是模块解析, 加载) 和 模块信息清单,
模块信息清单在每次有模块变更(hash 变更)时都会变更 */
},
cacheGroups:{//设置缓存chunks
priority: 0,//缓存组优先级
//当需要优先匹配缓存组的规则时,priority需要设置为正数,当需要优先匹配默认设置时,缓存组需设置为负数,0为两者分割线
default:{//设置缓存组默认配置,可通过default:false禁用默认缓存组,
//然后就可以自定义缓存组,将初始化加载时被重复引用的模块进行拆分
minChunks:2,//引用两次
priority:-20,//缓存组优先级为-20
reuseExistingChunk:true,//表示可以使用已经存在的块,即如果满足条件的块已经存在就是用己有的的,不再创建一个新的块
},
[key]:{//自定义缓存组,可以根据需求,自由创建
chunks:'initial',
test: /vue/,//正则规则验证,如符合就提取chunk放入当前缓存组,值可以是function、boolean、string、RegExp,默认为空
enforce: true//优先处理
}
}
三、疑难配置项
maxInitialRequests :
这个配置项我一直很不理解,网上的很多资源都是千篇一律,有用的基本没有,后来我发现了这篇文章 关于webpack模块拆分规则 让我有对这个配置项有了点浅显的了解
现在说说我的理解,举个小例子:
这是一个多页应用,index.js和shop.js是入口文件
我的目录结构:
;
这是webpack分割代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23runtimeChunk: {
name: 'manifest'
},
splitChunks: {
cacheGroups: {
//项目公共组件
common: {
chunks: 'initial',
name: 'common',
minChunks: 2,
maxInitialRequests: 3, //最大初始化加载次数,一个入口文件可以并行加载的最大文件数量,默认1
minSize: 0 //表示在分离前的最小模块大小,默认为0,最小为30000
},
//第三方组件
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
priority: 10,
enforce: true
}
}
}
现在先别急着看分包结果,先来分析一下:
其中除了React、ReactDOM是第三方包以外剩下的都是自定义组件
index.js(入口文件):React、ReactDom、index.jsx(index目录下)
shop.js(入口文件):React、ReactDom、index.jsx(shop目录下)
index.jsx(shop目录下):React、Header.jsx、A.jsx、B.jsx、shop.css
index.jsx(index目录下):React、A.jsx、index.css
A.jsx:React、Common.css
B.jsx:React、b.css、common.css
那么画出的依赖图就是这个样子:
这里来自 node_modules
的包肯定是被打包到 vender
里了,不用管这个,主要是看 common
这个包的信息
暂且忽略掉maxInitialRequests这个配置(当然代码里是不能忽略的因为有默认值,想象这一项不起作用就行了),如果按照使用次数超过2次,大小超过0的包,打包到一起,那么结果是这样的:
Common(chunks):A.jsx、Common.css
vender(chunks):第三方
shop.js(chunks):Header.jsx、B.jsx、b.css、shop.css
index.js(chunks):index.css
那么此时的maxInitialRequests(初始加载次数)是:shop页入口
:shop.js、vender、Common 一共三次
index页入口
:index.js、vender(chunks)、Common 一共三次
如果此时我限制了 maxInitialRequests:2 为2的话,那么结果是这样的
vender(chunks):第三方
shop.js(chunks):Header.jsx、B.jsx、b.css、shop.css、A.jsx、Common.css
index.js(chunks):index.css、A.jsx、Common.css
shop页入口
:shop.js、vender 一共两次
index页入口
:index.js、vender一共两次
看截图:
可以看到以上的分析是正确的
四、总结
不过话说会来,如果每次配置wepback的这一项都按这么分析,那得累死,可以这么分析,每次页面初始加载我想让它的并发请求不超过自己的预期就可以了