再見,CommonsChunkPlugin

發表於2018-04-16
webpack 4用兩個新的配置選項(optimization.splitChunks and optimization.runtimeChunk)替代了CommonsChunkPlugin。本文介紹這兩個新選項的用法。

預設值

預設情況下會做一些優化,對多數使用者都是合適的。

注意,預設值只會影響按需載入的塊,因為要修改初始(initial)塊會影響HTML中的script標籤。如果你可以自己處理(比如根據入口配置生成script標籤的時候),那可以對初始化也應用這些預設的優化:optimization.splitChunks.chunks: "all"

webpack根據如下條件自動拆分塊:

  • 新塊可以共享或者模組來自node_modules資料夾
  • 新塊會大於30kb(min+gz以前)
  • 按需載入塊之時最大的並行請求數小於等於5
  • 頁面初次載入時最大的並行請求數小於等於3

為盡力滿足後兩個條件,塊的體積可以更大。

下面看幾個例子。

例1

結果:會建立一個獨立的包含React的塊。在執行import呼叫時,這個塊會隨著包含./a的塊並行載入。

為什麼:

  • 條件1:這個塊包含的模組來自node_modules
  • 條件2:react大於30kb
  • 條件3:在執行import呼叫時,並行請求數是2
  • 條件4:不影響頁面初次載入

為什麼應該這樣拆分?

react可能不會像應用程式碼那樣經常變更。把它挪到一個獨立的塊,瀏覽器就可以快取它(假設你使用了長期快取配置:chunkhash、records、Cache-Control)。

例2

結果:會建立一個獨立的包含./helpers的塊。在執行import呼叫時,這個塊會與原始的塊並行載入。

為什麼:

  • 條件1:這個塊由兩個import呼叫共享
  • 條件2:helpers大於30kb
  • 條件3:在執行import呼叫時的並行請求數為2
  • 條件4:不影響頁面初次載入

為什麼應該這樣拆分?

讓helpers程式碼保留在每個塊中意味著使用者要下載它兩次,而獨立出來以後,則只需下載一次。實際上這也是有代價的,因為會多一次請求。這也是為什麼有最小30kb的限制的原因。


With optimizations.splitChunks.chunks: "all" the same would happend for initial chunks. Chunks can even be shared between entrypoints and on-demand loading.

配置

對於喜歡折騰的使用者,還有很多選項可供使用。

宣告:不要在沒有度量的情況下手工優化。預設值考慮了最佳實踐和Web效能。

快取組

這個選項將模組分配到快取組(cacheGroups)。

預設是將node_modules中的所有模組都分配到一個叫vendors的快取組,將至少在2個塊中重複出現的模組分配到另一個叫default的快取組。

一個模組可以被分配到多個快取組。這個優化通過priority選項或構成較大塊的模組來優先選擇快取組。

條件

在滿足所有條件的情況下,來自相同塊和快取組的模組會構成一個新塊。

有4個選項可以用於配置條件:

  • minSize (default: 30000) 塊的最小大小
  • minChunks (default: 1) 拆分前共享一個模組的最小塊數
  • maxInitialRequests (default 3) 一個入口最大並行請求數
  • maxAsyncRequests (default 5) 按需載入時最大行行請求數

命名

要控制拆分後新塊的名字,可以使用name選項。

注意:如果給不同的塊指定了相同的名字,結果就是這些塊會被合併成一個。這樣配置可以把所有vendor模組拆分為一個由所有入口點/拆分點共享的塊,但我不建議這樣用。因為這會導致下載的程式碼變多。

魔術值true會自動根據塊和快取組的鍵選擇一個名字。另外,除給這個選項傳一個字串,也可以傳一個函式。

如果名字與入口點名字相同,則刪除入口點。

選擇塊

通過chunks選項可以選擇塊,有3個值:"initial""async""all"。分別用於選擇初始塊、按需載入的塊和所有塊。

reuseExistingChunk選項用於配置在模組完全匹配時重用已有的塊,而不是建立新塊。

選擇塊可以針對每個快取組分別設定。

選擇模組

test選項控制當前快取組選擇哪個模組。省略表示選擇所有模組。值可以是RegExp、字串或函式。

可以匹配絕對模組資源的路徑或塊名字。如果匹配的是塊名字,則會選擇該塊中的所有模組。

配置快取組

以下是預設配置:

預設情況下,快取組會從splitChunks.*中繼承相應的選項值,而testpriorityreuseExistingChunk則只能在快取組層次上配置。

cacheGroups是一個物件,其中鍵是快取組的鍵,而值是選項(這是全部): chunksminSizeminChunksmaxAsyncRequestsmaxInitialRequests, name

要禁用預設組,傳入falseoptimization.splitChunks.cacheGroups.default: false

這裡預設快取組(default)的優先順序(priority)是負數,以便任意自定義的快取組都優先順序(預設為0)都會更高。

以下是一些配置的例項:

這樣就建立了一個commons塊,包含入口點共享的所有程式碼。

注意:這會導致使用者不必要地下載更多程式碼。

這樣就建立了一個vendors塊,包含整個應用中來自node_modules的所有程式碼。

注意:這會導致使用者不必要地下載更多程式碼。

optimization.runtimeChunk

optimization.runtimeChunk: true會給每個入口檔案的輸出再新增一個塊,其中只包含執行時。

相關文章