前言
以下摘自 webpack SplitChunksPlugin 官方文档
然而官方文档中只说明了 async
是默认的选项,关于 async
、initial
和 all
之间的区别却没有很好的进行举例解释。
今天我们将来探讨一下这三者的区别。
三种模式含义
- async表示动态引入的模块将会被拆分;
- initial表示不会将动态引入和静态引入的同一模块一起处理,而是分开处理;
- all对所有类型的模块进行拆分;
实验前准备
因为 webpack 将根据以下条件自动拆分 chunks:
- 新的 chunk 可以被共享,或者模块来自于
node_modules
文件夹- 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积)
- 当按需加载 chunks 时,并行请求的最大数量小于或等于 30
- 当加载初始化页面时,并发请求的最大数量小于或等于 30
因此本实验采用了两个第三方模块来做实验,分别是 lodash
和 moment
,因为他们的体积足够大;
本实验基于 [email protected] 从单入口和多入口 这两个方向进行测试;
本实验项目目录
// splitChunks.chunks
├── src
│ ├── index.js
│ ├── main-1.js
│ ├── main-2.js
├── webpack.config.js
单入口
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
mode: 'development',
output: {
clean: true,
filename: 'js/[name].[contenthash].js',
},
plugins: [
new HtmlWebpackPlugin(),
new BundleAnalyzerPlugin(),
],
optimization: {
splitChunks: {
chunks: 'async',
// chunks: 'initial',
// chunks: 'all',
},
},
};
src/index.js
import moment from 'moment';
import(/* webpackChunkName: 'lodash-index' */ 'lodash').then(({
default: lodash }) => {
lodash.findIndex([1, 2, 3]);
});
console.log('index', moment().format('YYYY-MM-DD HH:mm:ss'));
console.log('My index is running');
执行 npx wp
,可以得到如下打包结果
async 模式
可以看到最终打包出2️⃣个文件
其中动态引入的 lodash
被打包为 lodash-index.hash.js
;
index.js
打包为 main.hash.js
,其中包含了 moment
模块
initial 模式
可以看到最终打包出3️⃣个文件
其中动态引入的 lodash
依旧被打包为 lodash-index.hash.js
;
index.js
打包后被拆分为 main.hash.js
和 vendors-node_modules_moment_locale.js
all 模式
可以看到最终打包出3️⃣个文件,
其中动态引入的 lodash
依旧被打包为 lodash-index.hash.js
;
index.js
打包后被拆分为 main.hash.js
和 vendors-node_modules_moment_locale.js
这时的 all
和 initial
是没有区别的
结论
async | initial | all |
---|---|---|
在单入口的情况下 initial
和 all
模式是一样的,async
只会拆分动态引入的模块。
多入口
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
mode: 'development',
entry: {
main1: './src/main-1.js',
main2: './src/main-2.js',
},
output: {
clean: true,
filename: 'js/[name].[contenthash].js',
},
plugins: [
new HtmlWebpackPlugin(),
new BundleAnalyzerPlugin(),
],
optimization: {
splitChunks: {
chunks: 'async',
// chunks: 'initial',
// chunks: 'all',
},
},
};
src/mian-1.js
import moment from 'moment';
import(/* webpackChunkName: 'lodash-main-1' */ 'lodash').then(({
default: lodash }) => {
lodash.findIndex([1, 2, 3]);
});
console.log('main1', moment().format('YYYY-MM-DD HH:mm:ss'));
console.log('My main1 is running');
src/mian-2.js
import {
findIndex } from 'lodash';
import moment from 'moment';
findIndex([1, 2, 3]);
console.log('main2', moment().format('YYYY-MM-DD HH:mm:ss'));
console.log('My main2 is running');
执行 npx wp
,可以得到如下打包结果
async 模式
可以看到最终打包出3️⃣个文件,
其中 main-1.js
打包为 main1.hash.js
,其中包含了moment
模块
main-1.js
中动态引入的 lodash
被打包为 lodash-main-1.hash.js
;
main-2.js
打包为 main2.hash.js
,其中包含了 moment
、lodash
模块
分析
两个入口文件中都引入了
moment
、lodash
模块,但结果是这两个模块在整个的打包中都没有进行复用
initial 模式
可以看到最终打包出5️⃣个文件,
其中 main-1.js
打包后被拆分为 main1.hash.js
main-1.js
中动态引入的 lodash
被打包为 lodash-main-1.hash.js
;
main-1.js
中大模块 moment
被拆分为 vendors-node_modules_moment_locale.hash.js
main-2.js
打包后被拆分为 main2.hash.js
main-2.js
中静态引入的 lodash
被打包为 vendors-node_modules_lodash_lodash_js.b3a5668e68bc3ca616ad.js
;
main-2.js
中大模块 moment
被拆分为 vendors-node_modules_moment_locale.hash.js
,与 main-1.js
公用。
分析
两个入口文件中都引入了
moment
、lodash
模块,其中同为静态引入的 moment 模块在打包后被拆分为一个进行复用但分别动态引入和静态引入的 lodash 模块在打包后还是两个文件,没有进行复用
all 模式
可以看到最终打包出4️⃣个文件,
其中 main-1.js
打包后被拆分为 main1.hash.js
main-1.js
中动态引入的 lodash
被打包为 lodash-main-1.hash.js
;
main-1.js
中大模块 moment
被拆分为 vendors-node_modules_moment_locale.hash.js
main-2.js
打包后被拆分为 main2.hash.js
main-2.js
中静态引入的 lodash
打包后在关系图中没有显示,但实际是与 main-1.js
中动态引入 的 lodash
进行了复用;
main-2.js
中大模块 moment
被拆分为 vendors-node_modules_moment_locale.hash.js
,与 main-1.js
公用。
分析
两个入口文件中都引入了
moment
、lodash
模块,其中符合拆分条件的相同模块,无论是动态引入还是静态引入的,都被拆分为一个文件进行了复用
结论
async | initial | all |
---|---|---|
通常情况下,all
模式更为强大。像官网中生涩的描述:设置为 all
可能特别强大,因为这意味着 chunk 可以在异步和非异步 chunk 之间共享。
源码地址:https://gitee.com/yanhuakang/webpack-demos/tree/master/advanced/step_14-splitChunks/chunks