寫在前面
我們在上篇的文章中搬男,介紹了Code Splitting,其中有通過SplitChunksPlugin
加同步引入的方式進行代碼分割坡垫,和通過異步加載的方式讓webpack自動幫我們完成代碼分割隅居,上篇中,我們也是主要對代碼分割的概念和方式做了介紹和操作葛虐,其中提到的SplitChunksPlugin
和異步加載只是簡單使用了一下胎源,這篇我們將詳細(xì)學(xué)習(xí)SplitChunksPlugin
的參數(shù)配置和異步加載。
異步加載中的魔法注釋
我們再來看這段代碼
function getComponent () {
return import('lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b', 'c'])
return element
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
其中l(wèi)odash是一種通過異步引入的屿脐,那么webapck在打包的時候就會自動幫我們把代碼做分割涕蚤,我們知道現(xiàn)在lodash會生成一個0.js的文件宪卿,其實這是一個ID,那我們想把這個名字換成一個相應(yīng)的英文名字万栅,那該怎么做呢佑钾?這就是魔法注釋。我們將動態(tài)引入改成下面這樣
import(/* webpackChunkName:"lodash" */'lodash')
代表我們將異步引入的文件烦粒,打包后生成名為“l(fā)odash”的文件
再打包試一下休溶,這時候會發(fā)現(xiàn)目錄變成了這樣
|--dist
|--index.html
|--main.js
|--vendors~lodash.js
(對于一些webapck 低版本v4可能達(dá)到預(yù)期,這時候扰她,你需要裝一個官方的babel插件兽掰,讓異步加載來支持這種魔法注釋(@babel/plugin-syntax-dynamic-import
))
這時候有人就會疑問了“我們明明給他的文件明明是“l(fā)odash”為什么打包出來的文件前面加入了一個‘vendors~呢?’”加下來大家就和我一起學(xué)習(xí)插件SplitChunksPlugin
徒役。
SplitChunksPlugin
在上篇中孽尽,我們曾簡單用了它一下,體驗了一下code splitting忧勿,但其實他的配置內(nèi)容有很多杉女,這里我將對這個插件做詳細(xì)的配置講解,這是官網(wǎng)對他的介紹鸳吸,同學(xué)們也可以參考官網(wǎng)SplitChunksPlugin
我們將webpack.common.js
中的optimization
項先改成下面這樣熏挎,這次再對剛才的項目做打包看一下。
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: false,
default: false
}
}
},
我們發(fā)現(xiàn)打包文件中vendors~lodash.js
變成了lodash
晌砾。這說明
SplitChunksPlugin插件對于異步加載的模塊也是有影響的婆瓜,無論是我們做同步的代碼分割還是異步的代碼分割,我們都需要用到這個插件9备帷廉白!
下面就是每一個參數(shù)的詳解,看官網(wǎng)乖寒,這個插件是有一個默認(rèn)配置如下
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
}
}
}
我們將vendors和default都置為false猴蹂,以免對其他配置項進行影響。
chunks:initial
楣嘁、async
磅轻、all
chunks有三個值,意思是我們對哪種代碼做分割逐虚,有異步聋溜,有同步,有所有類型叭爱,上面的默認(rèn)配置中他的值是async
撮躁,意思是這個插件只對異步加載的模塊生效,下面我們將index.js中的模塊改成同步引入
import _ from 'lodash'
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b', 'c'])
document.body.appendChild(element)
打包一下买雾,大家可以看到把曼,對于同步的模塊引入是沒有進行代碼分割的杨帽,下面我們將chunks的值改為all,再打包一下嗤军,發(fā)現(xiàn)還是沒有生效哈注盈,這是因為,當(dāng)我們將chunks
的值設(shè)為all的時候叙赚,webpack會知道我們將對同步引入的模塊進行打包老客,但業(yè)務(wù)代碼中各種邏輯的引入其實一般都是同步引入的方式,這樣就會給分割帶來困難震叮,于是他會跳轉(zhuǎn)到cacheGroups
中查看相關(guān)配置胧砰,那現(xiàn)在我們先將cacheGroups.vendors
改為官網(wǎng)默認(rèn)的
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
這時候再打包,發(fā)現(xiàn)打包目錄變成了下面這樣
|--dist
|--index.html
|--main.js
|--vendors~main.js
意思是我們代碼分割成功了冤荆,看vendors.main.js
中,也是對lodash庫的引用权纤。vendors~main.js前面的vendors代表钓简,我們的lodash符合vendors組的要求,所以前綴就變成了這個組的名字汹想,其中的main代表這個庫的引入是入口是main.js,也就是其對應(yīng)的index.js外邓。
cacheGroups.vendors
有時候我們希望我們將所有的類庫都打包到一個'vendors.js'的文件中,這時候古掏,我們就可以在vendors.filename
中配置
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
filename: 'vendors.js'
},
這時候打包看一下损话。文檔目錄變成了這樣
|--dist
|--index.html
|--main.js
|--vendors.js
這樣配置的意思是,一旦我們對同步代碼做風(fēng)格槽唾,他就會到cacheGroups里面找匹配丧枪,一旦匹配了相應(yīng)的組,就會按照這個組的一些配置做相應(yīng)的分割庞萍,他和chunks
是配合使用的
minSize
當(dāng)引入的庫大于該值時才做代碼分割拧烦,小于的話就不做大嗎風(fēng)格了,大家可以在這里把minSize
設(shè)的特別大來驗證一下
cacheGroups.default
這里我們新建一個test.js導(dǎo)出一個特別簡單的內(nèi)容钝计,并將minSize
改為0恋博,來打包測試一下
export default {
name: 'hello webpack'
}
index.js
import test from './test'
console.log(test.name)
現(xiàn)在的內(nèi)容和你簡單,按照上面minsize的配置私恬,我們將其設(shè)為0债沮,他是理應(yīng)會執(zhí)行代碼分割的,但打包發(fā)現(xiàn)本鸣,他并沒有按照預(yù)期去執(zhí)行代碼分割疫衩,這是因為webpack在打包時,因其滿足minsize荣德,又是代碼隧土,就會去執(zhí)行cacheGroups
中的代碼提针,但他又不符合vendors
組的規(guī)則(不是node_modules下的內(nèi)容),所以就沒有將其正常風(fēng)格曹傀,這時候我們就需要用到cacheGroups.default
,我們先將官網(wǎng)的默認(rèn)配置拷貝過來辐脖,去掉cacheGroups.default.minChunks
參數(shù),執(zhí)行打包皆愉,我們發(fā)現(xiàn)嗜价,打包目錄變成了這樣
|--dist
|--index.html
|--main.js
|--default~main.js
其打包的命名規(guī)則和配置規(guī)則和cacheGroups.vendors
相同。我們也可以給其設(shè)置一個filename幕庐。
minChunks
minChunks代表一個模塊被應(yīng)用了多少次的時候才進行代碼分割久锥。
maxAsyncRequests
代表同時加載的模塊數(shù)最大值,這里的默認(rèn)值是5异剥,假如我們有10個模塊文件被分割瑟由,這里會將前五個模塊分割,其他的就不分割了冤寿,一般取默認(rèn)配置
maxInitialRequests
代表整個網(wǎng)站首頁加載的時候歹苦,入口文件最大的加載數(shù),如果入口文件引入的模塊數(shù)大于這個值督怜,其他的將不會被做代碼分割殴瘦,一般取默認(rèn)配置
automaticNameDelimiter
代表組和文件名之前的連接符
name
設(shè)置為true
代表我們在組中設(shè)置的文件名有效,一般不改默認(rèn)配置
cacheGroups.*.priority
代表組的權(quán)重号杠,有的模塊會同事滿足多個組的規(guī)則蚪腋,比如我們現(xiàn)在的lodash就同時滿足vendors
和default
兩個組的要求,這時候就需要一個權(quán)重值來讓模塊優(yōu)先執(zhí)行哪個組的打包姨蟋。
cacheGroups.**.reuseExistingChunk
默認(rèn)為true屉凯,遇到多個模塊相互引用的時候,當(dāng)一個模塊被重復(fù)使用眼溶,那么將不會重新打包神得,將使用之前打包的路徑
寫在最后
本篇也是比較詳細(xì)的介紹了SplitChunksPlugin
這個插件,其實其內(nèi)容還遠(yuǎn)比文章中介紹的多偷仿,有興趣的同學(xué)可以去官網(wǎng)再去查閱相關(guān)的資料哩簿。用好SplitChunksPlugin
你的代碼打包將變的效率更高,學(xué)習(xí)一下吧~