CommonsChunkPlugin主要是用來提取第三方庫和公共模塊应狱,避免首屏加載的bundle文件或者按需加載的bundle文件體積過大之宿,從而導(dǎo)致加載時(shí)間過長爱咬,是一把優(yōu)化項(xiàng)目的利器驰唬。
先來說一下各種教程以及文檔中CommonsChunkPlugin提及到chunk有哪幾種,主要有以下三種:
? ? ? ?1.webpack當(dāng)中配置的入口文件(entry)是chunk芯丧,可以理解為entry chunk
? ? ? ?2.入口文件以及它的依賴文件通過code split (代碼分割)出來的也是chunk芍阎,可以理解為children chunk
? ? ? ?3.通過commonsChunkPlugin創(chuàng)建出來的文件也是chunk,可以理解為commons chunk
CommonsChunkPlugin可配置的屬性:
name:可以是已經(jīng)存在的chunk(一般指入口文件)對應(yīng)的name缨恒,那么就會把公共模塊代碼合并到這個(gè)chunk上谴咸;否則,就會創(chuàng)建名字為name的commons chunk進(jìn)行合并
filename:指定commons chunk的文件名
chunks:指定該source chunk骗露,即指定從哪些chunk當(dāng)中去找公共模塊寿冕,省略該選項(xiàng)的時(shí)候,默認(rèn)就是entry chunks
minChunks:既可以數(shù)字椒袍,也可以是函數(shù),還可以是Infinity藻茂,具體用法和區(qū)別下面會說驹暑。
CommonsChunkPlugin插件的作用:
讓我們分三步講解:
1.不分離出第三方庫和自定義公共模塊
項(xiàng)目初始結(jié)構(gòu),后面打包后會生成dist目錄:
src目錄下各個(gè)文件內(nèi)容都很簡潔的辨赐,如下:
package.json文件:
webpack.config.js:
接著在命令行運(yùn)行npm run build优俘,此時(shí)項(xiàng)目中多了dist目錄:
再來看一下命令行中webpack的打包信息:
查看first.js和second.js,會發(fā)現(xiàn)共同引用的common.js文件和jquery都被打包進(jìn)去了掀序,這肯定不合理帆焕,公共模塊重復(fù)打包體積過大。
2.分離出第三方庫、自定義公共模塊叶雹、webpack運(yùn)行文件
這時(shí)候修改webpack.config.js新增一個(gè)入口文件vendor和CommonsChunkPlugin插件進(jìn)行公共模塊的提炔萍ⅰ:
查看dist目錄下,新增了一個(gè)vendor.js的文件:
再來查看一下命令行中webpack的打包信息:
通過查看vendor.js文件折晦,發(fā)現(xiàn)first.js和second.js文件中依賴的jquery和common.js都被打包進(jìn)vendor.js中钥星,同時(shí)還有webpack的運(yùn)行文件,總的來說满着,我們初步的目的達(dá)到谦炒,提取公共模塊,但是它們都在同一個(gè)文件中风喇。
到這里宁改,肯定有人希望自家的vendor.js純白無瑕,只包括第三方庫魂莫,不包括自定義的公共模塊和webpack運(yùn)行文件还蹲,又或者希望包含第三方庫和公共模塊,不包含webpack運(yùn)行文件豁鲤。
其實(shí)秽誊,這種想法是對的,特別是分離出webpack運(yùn)行文件琳骡,因?yàn)槊看未虬黽ebpack運(yùn)行文件都會變锅论,如果你不分離出webpack運(yùn)行文件,每次打包生成bendor.js對應(yīng)的哈希值都會變化楣号,導(dǎo)致vendor.js改變最易,但實(shí)際上你的第三方庫其實(shí)是沒有變,然而瀏覽器會認(rèn)為你原來緩存的vendor.js就失效炫狱,要重新去服務(wù)器中獲取藻懒,其實(shí)只是webpack運(yùn)行文件變化而已,就要人家重新加載视译,好冤啊嬉荆。。酷含。
那么怎么解決呢鄙早?
單獨(dú)分離出第三方庫、自定義公共模塊椅亚、webpack運(yùn)行文件
這里我們分兩步走:
1.先單獨(dú)抽離出webpack運(yùn)行文件
2.接著單獨(dú)抽離第三方庫和自定義公共模塊限番,這里利用minChunks有兩種方法可以完成,往后看就知道了呀舔。
1.抽離webpack運(yùn)行文件
先來抽離webpack運(yùn)行文件弥虐,修改webpack配置文件:
其實(shí)上面這段代碼,等價(jià)于下面這段:
上面這段抽離webpack運(yùn)行文件代碼的意思是創(chuàng)建一個(gè)名為runtime的commons chunk進(jìn)行webpack運(yùn)行文件的抽離,其中source chunks是vendor.js霜瘪。
查看dist目錄下珠插,新增了一個(gè)runtime.js的文件,其實(shí)就是webpack的運(yùn)行文件:
再來查看一下命令行中webpack的打包信息粥庄,你會發(fā)現(xiàn)vendor.js的體積已經(jīng)減小丧失,說明已經(jīng)把webpack運(yùn)行文件提取出來了:
可是,vendor.js中還有自定義的公共模塊common.js惜互,人家只想vendor.js擁有項(xiàng)目依賴的第三方庫而已(這里是jquery)布讹,這個(gè)時(shí)候把minChunks這個(gè)屬性引進(jìn)來。
minChunks可以設(shè)置為數(shù)字训堆、函數(shù)和Infinity描验,默認(rèn)值是2,并不是官方文檔說的入口文件的數(shù)量坑鱼,下面解釋下minChunks含義:
1.數(shù)字:模塊被多少個(gè)chunk公共引用才被抽取出來成為commons chunk
2.函數(shù):接受(module膘流,count)兩個(gè)參數(shù),返回一個(gè)布爾值鲁沥,你可以在函數(shù)內(nèi)進(jìn)行你規(guī)定好的邏輯來決定某個(gè)模塊是否提取成為commons chunk
3.Infinity:只有當(dāng)入口文件(entry chunks)>3才生效呼股,用來第三方庫中分離自定義的公共模塊
2、抽離第三方庫和自定義公共模塊
要在vendor.js中把第三方庫單獨(dú)抽離出來画恰,上面也說到了有兩種方法彭谁。
第一種方法minChunks設(shè)為Infinity,修改webpack配置文件如下:
查看dist目錄下允扇,新增了一個(gè)common.js的文件:
再來看一下命令行中webpack的打包信息缠局,自定義的公共模塊分離出來:
這時(shí)候的vendor.js就純白無瑕,只包含第三方文件考润,common.js就是自定義的公共模塊狭园,runtime.js就是webpack的運(yùn)行文件。
更多知識點(diǎn)請查看:https://segmentfault.com/a/1190000012828879