標籤:有一個 time script 分離 緩衝機制 update common 提取 一個
我們常常需要在瀏覽器緩衝一些穩定的資源,如第三方庫等。要達到這個目標,只需要兩步:1、提取出“穩定的資源”;2、提供穩定的檔案hash 。
webpack中提取公用模組一般使用 webpack 內建的 CommonsChunkPlugin 外掛程式,他可以提取出 入口chunk中 的公用模組:
1、minChunks 參數 是指 至少有minChunks個入口引用的模組才會提取出來,infinity等於入口數量,即所有入口都引用的模組才會提取出來;
上面的例子是一個SPA,入口是main.js。為了提取出第三方庫,我們新增一個vendors入口中,並引入所有用到的第三方庫,就像這樣:
裡面並沒有業務代碼,vendors檔案只是為了引導CommonsChunkPlugin外掛程式提取出 第三方庫!
2、names 參數 傳入數組,等效於 : (文檔的描述是:" 一個字串數組被傳入,這相當於外掛程式針對每個 chunk 名被多次調用")
其中,從vendors中提取manifest 的操作,我查看vue-cli的配置,裡面的注釋是這樣的 :
“extract webpack runtime and module manifest to its own file in order to prevent vendor hash from being updated whenever app bundle is updated”,
文檔解釋:
" 但是,如果我們改變應用的代碼並且再次運行 webpack,可以看到 vendor 檔案的 hash 改變了。即使我們把 vendor 和 main 的 bundle 分開了,也會發現 vendor bundle 會隨著應用代碼改變。
這意味著我們任然無法從瀏覽器緩衝機制中受益,因為 vendor 的 hash 在每次構建中都會改變,瀏覽器也必須重新負載檔案。
這裡的問題在於,每次構建時,webpack 產生了一些 webpack runtime 代碼,用來協助 webpack 完成其工作。當只有一個 bundle 的時候,runtime 代碼駐留在其中。但是當產生多個 bundle 的時候,運行時代碼被提取到了公用模組中,在這裡就是 vendor 檔案。
為了防止這種情況,我們需要將運行時代碼提取到一個單獨的 manifest 檔案中。儘管我們又建立了另一個 bundle,其開銷也被我們在 vendor 檔案的長期緩衝中獲得的好處所抵消。"
,大意就是,如果不把manifest提取出來,只要業務代碼有改動,
vendors(存放提取出來的第三方庫)檔案的內容也會變化,即它的chunkhash也會改變,這不是我們想要的!
3、hash 與 chunkhash:
[ hash ]是webpack編譯的hash值,每次編譯都不一樣;[ chunkhash ]則是根據檔案內容計算所得的hash值,檔案內容不變的話,這個值是固定的。
用webpack構建時,預設是css in js的,即css包含在js內,webpack計算chunkhash時,整個chunk的內容會將css的內容也計算在內。所以,不論是修改了js代碼還是css代碼,整個chunk的內容都改變了,計算所得的chunkhash隨之改變。
但理想情況下是想css或js內容改變時僅影響自身檔案的chunkhash,這樣用戶端只需更新一部分檔案。解決此問題首先要將css單獨編譯輸出檔案,並給他一個獨立的extracttextplugin外掛程式提供的 [ contenthash ] -- 根據常值內容產生的hash值。
把css提取出來後,就可以吧css單獨緩衝了!
webpack 的第三方庫分離並持久化緩衝