cacheGroups其實是splitChunks里面最核心的配置,一開始我還認為cacheGroups是可有可無的,這是完全錯誤的,splitChunks就是根據cacheGroups去拆分模塊的,包括之前說的chunks屬性和之后要介紹的種種屬性其實都是對緩存組進行配置的。splitChunks默認有兩個緩存組:vender和default,可以再來回顧一下splitChunks的默認配置:
module.exports = { //... optimization: { splitChunks: { chunks: 'async', minSize: 30000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } } } };
想想第一篇文章里為什么默認的打包能夠將第三方庫拆分出來,就是因為cacheGroups里面定義了vendors這個緩存組,它的test設置為 /[\\/]node_modules[\\/]/ 表示只篩選從node_modules文件夾下引入的模塊,所以所有第三方模塊才會被拆分出來。除此之外還有一個default緩存組,它會將至少有兩個chunk引入的模塊進行拆分,它的權重小於vendors,下面我們通過demo來測試一下。
我修改webpack的entry,新加入一個entry2.js,代碼如下:
webpack配置:

entry1.js
import React from 'react' import ReactDOM from 'react-dom' import $ from './assets/jquery' const App = () => { return ( <div> <div>entry1</div> </div> ) } ReactDOM.render(<App />, document.getElementById('root'))
entry2.js
import React from 'react' import ReactDOM from 'react-dom' import $ from './assets/jquery' const App = () => { return ( <div> <div>entry2</div> </div> ) } ReactDOM.render(<App />, document.getElementById('root'))
打包之后的結果如下:


entry1.js和entry2.js都引入了jquery.js,所以jquery.js的引用次數為2,minChunks的默認值為2,所以正好滿足要求於是第二個包被拆分出來了。
你當然也可以自己定義緩存組來根據你的項目實際情況進行耕細粒度的拆分。
另外還需要說明一下,cacheGroups之外設置的約束條件比如說默認配置里面的chunks、minSize、minChunks等等都會作用於cacheGroups,除了test, priority and reuseExistingChunk,這三個是只能定義在cacheGroup這一層的,這也就解釋了第一篇文章里面為什么entry里面引入的第三方庫react-dom只被entry1.js引入了一次就會被打包出來,因為默認的minChunks=1,這個屬性會作用於所有的cacheGroups,但是cacheGroups也可以將上面的所有屬性都重新定義,就會覆蓋外面的默認屬性,比如default這個緩存組就設置了minChunks=2,他會覆蓋掉默認值1。
注意:這塊再提一個思考,為什么entry1.js和entry2.js里面都引入了react-dom這個第三方庫,它完全滿足default這個cacheGroup的條件但是為什么沒有被包含在default~entry1~entry2這個chunk中而是被納入了vendor~entry1~entry2這個chunk里面了呢?
其實這是因為priority這個屬性起了作用,它的含義是權重,如果有一個模塊滿足了多個緩存組的條件就會去按照權重划分,誰的權重高就優先按照誰的規則處理,default的priority是-20明顯小於vendors的-10,所以會優先按照vendors這個緩存組拆分。
