避免公共模块重复打包的措施
- 使用 CommonsChunkPlugin 及其替代方案
- Webpack4 及之前:使用
CommonsChunkPlugin
。
- 配置思路:在
webpack.config.js
中,例如对于多入口配置如下:
const webpack = require('webpack');
module.exports = {
entry: {
page1: './src/page1.js',
page2: './src/page2.js'
},
output: {
path: __dirname + '/dist',
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'commons', // 抽取出来的公共模块的名称
chunks: ['page1', 'page2'], // 从哪些入口chunk中抽取公共模块
minChunks: 2 // 公共模块至少被引用的次数,这里表示至少被两个入口chunk引用
})
]
};
- Webpack5:
CommonsChunkPlugin
已被移除,使用 splitChunks
替代。
- 配置思路:在
webpack.config.js
中的 optimization
字段下配置,如下:
module.exports = {
entry: {
page1: './src/page1.js',
page2: './src/page2.js'
},
output: {
path: __dirname + '/dist',
filename: '[name].js'
},
optimization: {
splitChunks: {
chunks: 'all', // 对所有chunk进行分割
name: 'commons', // 公共模块名称
minSize: 30000, // 分割的模块最小大小
minChunks: 2 // 公共模块至少被引用的次数
}
}
};
- 插件原理
- CommonsChunkPlugin:它通过分析入口chunk的依赖关系树,找出多个chunk中重复引用的模块,并将这些模块提取出来放到一个单独的chunk中。这样在打包时,公共模块只会被打包一次,而不是在每个入口chunk中重复打包。
- splitChunks:
splitChunks
同样是基于分析chunk之间的依赖关系,将符合条件(如 minSize
、minChunks
等设定)的公共模块进行拆分并提取到单独的chunk中。它更加灵活和强大,不仅可以处理入口chunk之间的公共模块,还可以对异步chunk(如动态导入的模块)进行公共模块拆分。
- 根据项目实际情况优化
- 公共模块大小:如果公共模块较小,可以适当降低
minSize
的值(在 splitChunks
中)或增加 minChunks
的值,避免过多小的公共模块文件产生,减少请求数。例如,如果项目中公共模块大多在 10 - 20KB 左右,可以将 minSize
设为 10000(10KB)。
- 动态导入模块:对于项目中使用动态导入(
import()
)的模块,如果这些模块之间有公共部分,可以通过 splitChunks
的 cacheGroups
配置,对异步chunk进行更细粒度的公共模块拆分。比如:
optimization: {
splitChunks: {
cacheGroups: {
asyncCommons: {
name: 'async - commons',
chunks: 'async',
minChunks: 2
}
}
}
}
- 第三方库分离:对于项目中使用的第三方库(如
lodash
、react
等),可以单独配置一个 cacheGroup
将它们提取到一个单独的文件中,实现长期缓存。例如:
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name:'vendor',
test: /[\\/]node_modules[\\/]/,
chunks: 'all'
}
}
}
}