资源缓存
webpack为了更加高效的打包,认为一些没有变动的内容不要再次打包了,因此可以在一些输出启动模板字符串(Template strings)使用contenthash
let output = {
...output,
filename: '[name][contenthash].js',
clean: false, // 注意这非常重要
}
这样做,如果打包的资源没有发生变化就不需要重新打包资源,节省了webpack打包时间和性能。但是会有个问题,A、B模块之间引用,模块A发生变化,那么它的contenthash和文件名发生变化,但是B引入了A,B没有发生变化,B没有重新打包,那么B的导入是的模块名称就失效了(还是之前的A的contenthash)。
解决办法是将runtimeChunk单独打包出来,每次生成新的runtimeChunk。
const optimization = {
runtimeChunk: '', // runtimeChunk 单独打包的配置
}
需要注意,不要滥用contenthash这些占位符,每次运算contenthash也需要时间
SplitChunksPlugin
它的作用就像名字一样,分割chunks,为什么在这里讲它,明明是《资源缓存》篇。
场景:第三方的插件比如lodash,一般在开发中基本不改变,因此可以把所有的插件打包成一个文件,在每次打包的时候就可以重复使用而不用重新打包和下载:
const optimization = {
splitChunks: {
// chunks: 'all' ---
cacheGroups: { // 缓存项
vendor: {
test: /[\\/]node_modules[\\/]/,
// 把使用到的第三方的包都打包到vendors这个chunk里
name: 'vendors',
chunks: 'all'
}
}
}
}
optimization.splitChunks的配置选项
开箱即用SplitChunksPlugin应该适用于大多数用户。 默认情况下,它只影响按需块,因为更改初始块会影响 HTML 文件应包含以运行项目的脚本标记。 Webpack 将根据这些条件自动拆分块:
- 可以共享新块或模块来自node_modules文件夹
- 新块将大于 20kb(在 min+gz 之前),其实是权衡 请求数量和请求数据量
- 按需加载块时的最大并行请求数将低于或等于 30
- 初始页面加载时的最大并行请求数将低于或等于 30
当试图满足最后两个条件时,首选更大的块
当然要用户可以更加细致化的定义改如何的去split:
-
optimization.splitChunks.chunks:
- async:只提取异步加载的模块出来打包到一个文件中
- initial:提取同步加载和异步加载模块,如果xxx在项目中异步加载了,也同步加载了,那么xxx这个模块会被提取两次,分别打包到不同的文件中
- all:不管异步加载还是同步加载的模块都提取出来,打包到一个文件中
-
splitChunks.maxInitialRequests 初始页面加载时的最大并行请求数 ,默认为30
-
splitChunks.maxAsyncRequests 按需加载块时的最大并行请求,默认为30
-
splitChunks.minSize 在 min + gz 之前,最小的块必须为多少,默认 20000b
-
splitChunks.minChunks 在拆分这个模块之前判断,这个模块是不是被共享最少 minChunks 次,才允许拆分
-
splitChunks.cacheGroups,代码分割缓存组:它是一个对象,key为打包成缓存的chunk名,value为split配置:
- priority:number,当前 cacheChunk 的分割优先级(注意上面有maxAsyncRequests、maxInitialRequests等限制,因此会选取优先级高的进行分割)
- reuseExistingChunk:true,如果当前块包含已经从主包中分离出来的模块,它将被重用,而不是生成一个新的
- type 缓存分组
- test:控制此缓存组选择哪些模块。省略它会选择所有模块。它可以匹配绝对模块资源路径或块名称。当块名称匹配时,块中的所有模块都会被选中
- name 生成的chunk的名字
- enforce 强制的(忽略minSize,minChunks)
- ...splitChunks,cacheGroup的配置项能够继承 和 覆盖的 splitChunks属性(相当于splitChunks的属性是cacheGroups配置项所有的默认配置)
splitChunks的cacheGroups 非常强大,能把匹配到的的所有 文件打包到一起进行缓存,并且打包的时候还可以分割。