webapck4 玄妙的 SplitChunks Plugin
webpack 4捨棄了之前的 commonChunkPlugin
,增加了 SplitChunksPlugin
, 對於這個外掛,它的 option
選項有 initial
、 async
、 all
三個值。我想大多數剛學習 webpack 4
的同學應該都不能很好的理解這幾個值的區別,到底每個選項值是啥意思,我們來手把手實踐一下。
原文連結: ofollow,noindex">Webpack 4 — Mysterious SplitChunks Plugin
幾點說明:
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
,我打包的時候只關心動態載入的模組,其他的你隨便玩。