原文地址: webpack 4: Code Splitting, chunk graph and the splitChunks optimization
原文做者: Tobias Koppers
譯者: arzh
推薦理由: 從webpack3
升級到webpack4
所作的重要更改vue
webpack4
對chunk
圖進行了一些重大改進,併爲chunk
拆分添加了一個新的優化(這是對CommonsChunkPlugin
的一種改進)node
讓咱們來看看舊版關係圖的一些缺點react
在舊圖中,chunks
經過父子關係和chunks
包含模塊來鏈接其餘的chunks
webpack
當一個chunk
有多個父節點的話,咱們能夠認爲當這個chunk
被加載的時候,至少有一個父節點已經被加載了.這個信息能夠被用來優化,例如,當一個chunk
的模塊,在全部父節點均可用時,它能夠從chunk
中被移除,由於它必定已經被成功加載了。web
在入口點或異步拆分點處引用chunk
列表時,這些chunks
會並行加載。緩存
這種類型的關係圖使得分離chunks
變得十分困難,例如使用CommonsChunkPlugin
會有這樣的問題,當你刪除一個或多個chunks
模塊,並將它們放在一個新的chunk
中,這個新的chunk
須要被從新鏈接到關係圖中,可是如何鏈接呢?做爲舊的chunk的父級,仍是子級?CommonsChunkPlugin
將其添加爲父級,但這在技術上是錯誤的,同時也會對其餘優化產生負面影響(父節點信息是不許確的)dom
新的chunk
圖中引入了一個新對象: ChunkGroup
,一個ChunkGroup
包含多個chunk
異步
在入口點或異步拆分點處引用單個ChunkGroup
,這意味着全部被ChunkGroup
包含的chunk
都是並行加載的。一個chunk
能夠被引用在多個ChunkGroup
中(但不會被加載屢次)優化
如今就再也不使用父子關係來關聯chunk
,而是經過ChunkGroup
來進行關聯插件
如今chunks
的分割能夠被理解了,新增長的chunks
會被添加到全部包含原始chunk
的ChunkGroups
中,這並不會對父層級關係產生負面影響。
如今這個問題被修復了,咱們就能夠開始更多的使用chunk
分離了,咱們能夠任意拆分chunk
而不用擔憂chunk
圖會被破壞
CommonsChunkPlugin
有許多的問題:
chunks
下是低效率的因此新的插件誕生了:SplitChunksPlugin
它能經過heuristics
自動識別應該被分塊的模塊,使用模塊重複計數和模塊類別(如node_modules
),來分割chunks
這裏有一種二者的比喻。CommonsChunkPlugin
就像:"建立一個chunk
並將匹配minChunks
的全部模塊移動到新塊中",SplitChunksPlugin
就像:"這是heuristics
,確保你知足他們"(Here are the heuristics, make sure you fullfil them)(命令式與聲明式的區別)
SplitChunksPlugin
也有一些很棒的屬性:
chunk
合併)chunks
下也是高效的chunks
模式分割chunk
圖如下是SplitChunksPlugin
爲你列舉的幾個例子。這些示例僅顯示默認行爲,附加配置有更多個性化的選擇
注意:你能夠經過optimization.splitChunks
進行配置。這些示例說明了一些關於chunk
的內容,默認狀況下它只適用於異步chunk
,可是使用optimization.splitChunks.chunks:"all"
來配置,適用於全部類型的文件(同步、異步chunk
)
注意:咱們假設此處使用的每一個外部庫都大於30kb
,由於代碼優化僅在超出此大小以後才能生效。
chunk-a: react
, react-dom
, some components
chunk-b: react
, react-dom
, some other components
chunk-c: angular
, some components
chunk-d: angular
, some other components
webpack將會自動建立兩個vendors chunks
,結果以下:
vendors~chunk-a~chunk-b: react
, react-dom
vendors~chunk-c~chunk-d: angular
chunk-a to chunk-d: Only the components
chunk-a: react
, react-dom
, some components
chunk-b: react
, react-dom
, lodash
, some other components
chunk-c: react
, react-dom
, lodash
, some components
webpack也會建立兩個vendors chunks
,結果以下:
vendors~chunk-a~chunk-b~chunk-c: react
, react-dom
vendors~chunk-b~chunk-c:lodash
chunk-a to chunk-c: Only the components
chunk-a: vue
, some components
, some shared components
chunk-b: vue
, some other components
, some shared components
chunk-c: vue
, some more components
, some shared components
假設共享組件的大小大於30kb
,webpack
將建立一個vendors chunk
和一個commons chunk
,結果以下:
vendors~chunk-a~chunk-b~chunk-c: vue
commons~chunk-a~chunk-b~chunk-c: some shared components
chunk-a to chunk-c: Only the components
當這些shared components
體積小於30kb
時,webpack
會特地將該模塊複製到chunk-a chunk-b chunk-c
三個文件中。他們認爲進行分離所減少的加載體積的總體效果並不如一次額外的加載請求的消耗。
chunk-a: react
, react-dom
, some components
, some shared react components
chunk-b: react
,react-dom
, angular
, some other components
chunk-c: react
,react-dom
, angular
, some components
, some shared react components
, some shared angular components
chunk-d: angular
, some other components
, some shared angular components
webpack將建立兩個vendors chunk
和兩個commons chunk
,結果以下:
vendors~chunk-a~chunk-b~chunk-c: react
, react-dom
vendors~chunk-b~chunk-c~chunk-d: angular
commons~chunk-a~chunk-c: some shared react components
commons~chunk-c~chunk-d: some shared angular components
chunk-a to chunk-d: Only the components
注意:因爲chunk
名稱包括全部原始chunk
名稱,所以建議使用長期緩存的生產版本不包括文件名中的[name]
,或經過optimization.splitChunks.name:false
關閉名稱生成.這樣在後續開發中添加了新的引用,也不會變動文件名。
對本文有任何優化建議,可掃描下述二維碼一塊兒討論,同時也但願你們多多關注,會不按期發送一些原創文章