學習webpack時官網推薦文檔使用CommonsChunkPlugin,但The CommonsChunkPlugin 已經從
webpack v4 legato 中移除.借鑑其餘寫的文章加上原文進行總結.
參考: 沒有了CommonsChunkPlugin,咱拿什麼來分包 [1]:
https://blog.csdn.net/songluy...
起初,chunks(代碼塊)和導入他們中的模塊經過webpack內部的父子關係圖鏈接.CommonsChunkPlugin被用來避免他們之間的依賴重複,可是沒有更多的優化.html
從4.0版本開始CommonsChunkPlugin被移除且被optimization.splitChunks和optimization.runtimeChunk配置項代替.下面展現它們將如何工做.node
SplitChunksPlugin 拆箱即用 對於大多數的用戶很好用.
默認狀況下它將只會影響按需加載的代碼塊,由於改變初始化的代碼塊將會影響html中運行項目須要包含的script標籤.react
webpack將會基於如下條件自動分割代碼塊:webpack
爲了知足以上最後兩個條件,傾向於更大的代碼塊.
讓咱們看一些簡單的例子.web
// index.js // dynamically import a.js import("./a");
// a.js import "react"; // ...
結果:一個包含react的單獨代碼塊將會被建立.由於index.js在import '/a.js'時和a.js中都會記載這個代碼塊.瀏覽器
緣由:緩存
這樣作的理由是? react 不會像你的應用代碼同樣常常改變.經過將它放到一個單獨的代碼塊中能夠與你本身的代碼分離開來,從而被獨立緩存(假設你正在用chunkhash, records, Cache-Control等長期緩存策略).框架
// entry.js // dynamically import a.js and b.js import("./a"); import("./b");
// a.js import "./helpers"; // helpers is 40kb in size // ...
// b.js import "./helpers"; import "./more-helpers"; // more-helpers is also 40kb in size // ...
結果:一個包含'./helpers'和全部關於它的依賴的代碼塊將會被建立.當調用import時,這個代碼塊一塊兒被加載進原始代碼塊.async
緣由:模塊化
將helpers的內容放進各個代碼塊將會致使helpers的代碼被下載兩次.經過使用分離的代碼塊將會只下載一次.咱們將會多發起一塊兒請求helpers的請求,若是代碼塊太小則不值得多發起一次請求,折中的建議是代碼塊超過30kb再進行分離.
爲了讓開發者們對這個功能有更多的控制,webpack提供了一些配置項來更好的知足你的需求.
在人爲改變分割配置時,請肯定自定義配置帶來了實實在在的好處.
默認配置便是咱們推薦的web最佳實踐,可是你項目的最佳策略根據項目類型可能會有所不一樣
默認將全部來源於node_modules的模塊分配到叫作'venders'的緩存組,全部引用超過兩次的模塊分配到'default'緩存組.
一個模塊能夠被分配到多個緩存組.這個優化能夠經過選擇更高優先級的緩存組或者造成代碼塊更大的緩存組來完成.
當知足下列全部條件時,來自同一個代碼塊和緩存組的模塊將會造成一個新的代碼塊.
下面條件的4個配置項:
能夠經過'name'配置項來控制切割以後代碼塊的命名.
給多個分割以後的代碼塊分配相同的名稱,全部的vendor 模塊被放進一個共享的代碼塊中,不過這會致使多餘的代碼被下載因此並不推薦
神奇的true值將會自動根據切割以前的代碼塊和緩存組鍵值(key)自動分配命名,不然就須要傳入一個String或者function.
命名與入口名稱相同時,入口將會被移除.
optimization.splitChunks.automaticNameDelimiter
默認webpack將會使用入口名和代碼塊的名稱生成命名,好比 'vendors~main.js'
若是你的工程和"~"衝突,能夠經過設置automaticNameDelimiter:'-'解決.
以後最終的命名將會是'vendors-main.js'
test配置項控制這個緩存組所選擇的的模塊.忽略它選擇全部模塊.這個配置能夠是正則,字符串或者是函數.
能夠匹配絕對資源路徑或者是代碼塊名.當一個代碼塊名稱被匹配,全部在這個代碼塊中的模塊都會被選則.
能夠用chunks配置項來指定代碼塊會被切割.
可用值:"initial","async","all".配置以後只會選擇對應於初始化代碼塊,按需加載代碼塊,或者是全部代碼塊中的一個.
當模塊徹底匹配時,reuseExistingChunk 配置項容許重用已經存在的代碼塊而不是建立一個新的代碼塊.
每個緩存組均可以使用這個配置項來控制.
optimization.splitChunks.chunks: all
就像以前提到的這個插件會影響動態導入的模塊.設置chunks配置項爲all將會影響初始化的代碼塊(即便不是動態導入的代碼塊).這種代碼塊將會被入口和按需加載共享.
下面是建議的配置:
這個配置能夠配合HtmlWebpackPlugin插件使用,這將爲你注入全部生成的vendor代碼塊.
下面的配置對象表明了splitChunksPlugin的默認行爲.
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 } } }
緩存組默認繼承splitChunks的配置項,可是test,priority和reuseExistingChunk只能在緩存組中被配置.
緩存組是一個是緩存組名字做爲鍵值的對象.除了上述代碼塊中列舉的配置項還有:chunks, minSize, minChunks, maxAsyncRequests, maxInitialRequests, name.
你能夠設置optimization.splitChunks.cacheGroups.default = false來禁用默認緩存組,
vendors也能夠一樣禁用.
爲了可以讓自定義緩存組有更高的優先級(默認0),默認緩存組的priority屬性爲負值.
下面是一些例子和他們的影響:
建立名爲"commons"的代碼塊,它包含了入口之間共享的全部代碼.
splitChunks: { cacheGroups: { commons: { name: "commons", chunks: "initial", minChunks: 2 } } }
這個配置會增大你的初始化包,當一個模塊不是當即被須要建議採用動態導入.
建立一個vendor代碼塊,它包含了整個應用中全部來自node_modules的代碼.
splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: "vendors", chunks: "all" } } }
這會致使一個包含全部外部包的大代碼塊.建議只包括你的核心框架和功能,而且動態加載剩餘的依賴.
注意:這可能會致使下載額外的代碼。
設置optimization.runtimeChunk=true ,將每個入口添加一個只包含runtime的額外代碼塊.
然而設置值爲single,只會爲全部生成的代碼塊建立一個共享的runtime文件.
runtime:鏈接模塊化應用程序的全部代碼. runtime包含:在模塊交互時,鏈接模塊所需的加載和解析邏輯。包括瀏覽器中的已加載模塊的鏈接,以及懶加載模塊的執行邏輯.