在 Webpack 中,总共提供了三种方式来实现代码分割(Code Splitting):
import() 或者 require.ensure 来动态加载SplitChunksPlugin 配置来抽取公共代码抽取公共代码资源有两种方式:
html-webpack-externals-plugin 进行基础库分离SplitChunksPlugin 进行公共脚本分离着重讲一下 SplitChunksPlugin。
思路:将 react、React-dom 基础包通过 cdn 引入,不打入 bundle 中。
// webpack.config.js
module.exports = {
//...
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [
{
module: 'react',
entry: '<https://11.url.cn/now/lib/16.2.0/react.min.js>',
global: 'React',
},
{
module: 'react-dom',
entry: '<https://11.url.cn/now/lib/16.2.0/react-dom.min.js>',
global: 'ReactDOM',
}
]
})
]
}
webpack 4 内置 (webpack 4 之前使用 CommonsChunkPlugin)。
splitChunks 默认配置:
// webpack.config.js
module.exports = {
// ...
optimization: {
splitChunks: {
chunks: 'async', // 三选一: 'initial' | 'all' | 'async' (默认)
minSize: 30000, // 最小尺寸,30K,development 下是 10k,越大那么单个文件越大,chunk 数就会变少(针对于提取公共 chunk 的时候,不管再大也不会把动态加载的模块合并到初始化模块中)当这个值很大的时候就不会做公共部分的抽取了
maxSize: 0, // 文件的最大尺寸,0 为不限制,优先级:maxInitialRequest/maxAsyncRequests < maxSize < minSize
minChunks: 1, // 默认 1,被提取的一个模块至少需要在几个 chunk 中被引用,这个值越大,抽取出来的文件就越小
maxAsyncRequests: 5, // 在做一次按需加载的时候最多有多少个异步请求,为 1 的时候就不会抽取公共 chunk 了
maxInitialRequests: 3, // 针对一个 entry 做初始化模块分隔的时候的最大文件数,优先级高于 cacheGroup,所以为 1 的时候就不会抽取 initial common 了
automaticNameDelimiter: '~', // 打包文件名分隔符
name: true, // 拆分出来文件的名字,默认为 true,表示自动生成文件名,如果设置为固定的字符串那么所有的 chunk 都会被合并成一个
cacheGroups: {
vendors: {
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/, // 正则规则,如果符合就提取 chunk
priority: -10, // 缓存组优先级,当一个模块可能属于多个 chunkGroup,这里是优先级
},
default: {
minChunks: 2,
priority: -20, // 优先级
reuseExistingChunk: true, // 如果该 chunk 包含的 modules 都已经另一个被分割的 chunk 中存在,那么直接引用已存在的 chunk,不会再重新产生一个
}
}
}
}
}
splitChunks 默认配置对应的就是 chunk 生成的第二种情况:动态加载(按需加载):通过写代码时主动使用 import() 或者 require.ensure 来动态加载。
async(默认):异步引入(动态引入)的代码进行拆分initial:同步引入的代码进行拆分,而异步引入(动态引入)不受影响,无论如何都会被拆分出去