webpack 4 舍弃了之前的 commonChunkPlugin, 增加了 SplitChunksPlugin, 对于这个插件, 它的 option 选项有 initial,async,all 三个值. 我想大多数刚学习 webpack 4 的同学应该都不能很好的理解这几个值的区别, 到底每个选项值是啥意思, 我们来手把手实践一下.
几点说明:
这篇文章是看了上面这篇洋文文章之后进行的一次实践
动手后发现和原文中的结果并不完全一样, 估计是原文中没有写 name 字段的缘故.
官方文档
我们做一个粗略的尝试, 思路是有两个 a.JS 和 b.JS 两个入口文件, 引入相同的模块, 区别是一些模块是动态引入的, 以此来摸索一下 Code-Spliting.
开始之前
坠重要的当然是配置一下 webpack 环境
初始化
- mkdir splitTest
- cd splitTest
- NPM init -y
安装依赖
- NPM i react jQuery loadsh -S
- NPM 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 里面.
来源: https://juejin.im/post/5c08fe7d6fb9a04a0d56a702