webpack代碼分割之SplitChunksPlugin和魔法注釋

webpack.jpg

寫在前面

我們在上篇的文章中搬男,介紹了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就同時滿足vendorsdefault兩個組的要求,這時候就需要一個權(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í)一下吧~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酝静,一起剝皮案震驚了整個濱河市节榜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌别智,老刑警劉巖宗苍,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡讳窟,警方通過查閱死者的電腦和手機让歼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丽啡,“玉大人谋右,你說我怎么就攤上這事〔构浚” “怎么了改执?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坑雅。 經(jīng)常有香客問我辈挂,道長,這世上最難降的妖魔是什么裹粤? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任终蒂,我火速辦了婚禮,結(jié)果婚禮上遥诉,老公的妹妹穿的比我還像新娘拇泣。我一直安慰自己,他們只是感情好突那,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布挫酿。 她就那樣靜靜地躺著构眯,像睡著了一般愕难。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惫霸,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天猫缭,我揣著相機與錄音,去河邊找鬼壹店。 笑死猜丹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的硅卢。 我是一名探鬼主播射窒,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼将塑!你這毒婦竟也來了脉顿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤点寥,失蹤者是張志新(化名)和其女友劉穎艾疟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡蔽莱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年弟疆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盗冷。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡怠苔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出正塌,到底是詐尸還是另有隱情嘀略,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布乓诽,位于F島的核電站帜羊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鸠天。R本人自食惡果不足惜讼育,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稠集。 院中可真熱鬧奶段,春花似錦、人聲如沸剥纷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晦鞋。三九已至蹲缠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悠垛,已是汗流浹背线定。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留确买,地道東北人斤讥。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像湾趾,于是被迫代替她去往敵國和親芭商。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355