webpack 4舍弃了之前的
commonChunkPlugin
,增加了SplitChunksPlugin
, 对于这个插件,它的option
选项有initial
、async
、all
三个值。我想大多数刚学习webpack 4
的同学应该都不能很好的理解这几个值的区别,到底每个选项值是啥意思,我们来手把手实践一下。
原文链接:
几点说明:
- 这篇文章是看了上面这篇洋文文章之后进行的一次实践
- 动手后发现和原文中的结果并不完全一样,估计是原文中没有写
name
字段的缘故。
我们做一个粗略的尝试,思路是有两个a.js
和b.js
两个入口文件,引入相同的模块,区别是一些模块是动态引入的,以此来摸索一下Code-Spliting
。
开始之前
坠重要的当然是配置一下webpack环境
- 初始化
mkdir splitTestcd splitTestnpm init -y复制代码
- 安装依赖
npm i react jquery loadsh -Snpm i webpack webpack-bundle-analyzer webpack-cli @babel/core @babel/plugin-syntax-dynamic-import -D复制代码
- webpack配置
webpack.config.js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');module.exports = { mode: 'production', entry: { a: './src/a.js', b: './src/b.js' }, output: { filename: '[name].bundle.js' }, module: { rules: [ { test: /\.(js)$/, loader: 'babel-loader', exclude: /node_modules/ } ] }, plugins: [ new BundleAnalyzerPlugin() ], optimization: { splitChunks: { cacheGroups: { vendor: { test: /node_modules/, name: 'vendors', // 这个字段不写结果会不一样,可以尝试一下,我目前没整明白,求大佬解答 chunks: 'initial', } } } }}复制代码
package.json
"scripts": { "build": "webpack --config webpack.config.js"}复制代码
.babelrc
{ "plugins": [ "@babel/plugin-syntax-dynamic-import" ]}复制代码
- a.js
import 'react';import 'jquery';import ('lodash');console.log('I am angry!');var a = 10;export default a;复制代码
- b.js
import ('react');import ('lodash');import 'jquery';console.log('I am Exciting!');var b = 10;export default b;复制代码
采用控制变量法,我们来试验当存在公共库的时候,webpack是怎么处理的
- 1 一个动态引入,另个一不 (React)
- 2 两个都不动态加载 (JQuery)
- 3 两个都动态加载 (lodash)
画了个比较挫的图,大概描述一下
准备工作都弄好了
chunks: 'initial'
...vendor: { test: /node_modules/, chunks: 'initial', priority: 1,}...复制代码
从图中我们可以看出:
- 1
JQuery
和react
被打到vendors.bundle.js
里,被a.js
和b.js
共享,由于react
在a.js
中不是动态加载的,所以也被打进去了 - 2
lodash
被打到1.bundle.js
中 因为这是两个文件共有的动态模块 - 3
b.js
中的react
被打到4.bundle.js
中
chunks: 'async'
看看发生了什么:
webpack
从b.js
中抽离了react
,扔到一个新文件,a.js
中的react
不动。这个优化只会作用到动态模块,import('react')
声明会产生独立的文件,import 'react'
则不会a.js
和b.js
共有的动态模块lodash
被移动到一个新文件。- 没有
JQuery
进行优化,尽管a.js
和b.js
都引用了
相当于告诉webpack
,我打包的时候只关心动态加载的模块,其他的你随便玩。
chunks: 'all'
所有模块都被扔到了vendors.bundle.js
里面。