hash 計算與整個項目的構建相關;chunkhash 計算與同一 chunk 內容相關;contenthash 計算與文件內容本身相關。 ...
Webpack 有非常多的概念,很多名詞長得都差不多。我把這些分散在文檔和教程里的內容總結起來,寫了一份 webpack 中的易混淆知識點,目前看是全網獨一份,大家可以加個收藏,方便以後檢索和學習。
全集鏈接 ➡️ webpack 易混淆知識點
首先來個背景介紹,哈希一般是結合 CDN 緩存來使用的。如果文件內容改變的話,那麼對應文件哈希值也會改變,對應的 HTML 引用的 URL 地址也會改變,觸發 CDN 伺服器從源伺服器上拉取對應數據,進而更新本地緩存。
4.1 hash
hash 計算是跟整個項目的構建相關,我們做一個簡單的 demo。
沿用案例 1 的 demo 代碼,文件目錄如下:
src/
├── index.css
├── index.html
├── index.js
└── utils.js
webpack 的核心配置如下(省略了一些 module 配置信息):
{
entry: {
index: "../src/index.js",
utils: '../src/utils.js',
},
output: {
filename: "[name].[hash].js", // 改為 hash
},
......
plugins: [
new MiniCssExtractPlugin({
filename: 'index.[hash].css' // 改為 hash
}),
]
}
生成的文件名如下:
我們可以發現,生成文件的 hash 和項目的構建 hash 都是一模一樣的。
4.2 chunkhash
因為 hash 是項目構建的哈希值,項目中如果有些變動,hash 一定會變,比如說我改動了 utils.js 的代碼,index.js 里的代碼雖然沒有改變,但是大家都是用的同一份 hash。hash 一變,緩存一定失效了,這樣子是沒辦法實現 CDN 和瀏覽器緩存的。
chunkhash 就是解決這個問題的,它根據不同的入口文件(Entry)進行依賴文件解析、構建對應的 chunk,生成對應的哈希值。
我們再舉個例子,我們對 utils.js 里文件進行改動:
export function square(x) {
return x * x;
}
// 增加 cube() 求立方函數
export function cube(x) {
return x * x * x;
}
然後把 webpack 里的所有 hash 改為 chunkhash:
{
entry: {
index: "../src/index.js",
utils: '../src/utils.js',
},
output: {
filename: "[name].[chunkhash].js", // 改為 chunkhash
},
......
plugins: [
new MiniCssExtractPlugin({
filename: 'index.[chunkhash].css' // // 改為 chunkhash
}),
]
}
構建結果如下:
我們可以看出,chunk 0 的 hash 都是一樣的,chunk 1 的 hash 和上面的不一樣。
假設我又把 utils.js 里的 cube() 函數去掉,再打包:
對比可以發現,只有 chunk 1 的 hash 發生變化,chunk 0 的 hash 還是原來的。
4.3 contenthash
我們更近一步,index.js 和 index.css 同為一個 chunk,如果 index.js 內容發生變化,但是 index.css 沒有變化,打包後他們的 hash 都發生變化,這對 css 文件來說是一種浪費。如何解決這個問題呢?
contenthash 將根據資源內容創建出唯一 hash,也就是說文件內容不變,hash 就不變。
我們修改一下 webpack 的配置:
{
entry: {
index: "../src/index.js",
utils: '../src/utils.js',
},
output: {
filename: "[name].[chunkhash].js",
},
......
plugins: [
new MiniCssExtractPlugin({
filename: 'index.[contenthash].css' // 這裡改為 contenthash
}),
]
}
我們對 index.js 文件做了 3 次修改(就是改了改 log 函數的輸出內容,過於簡單就先不寫了),然後分別構建,結果截圖如下:
我們可以發現,css 文件的 hash 都沒有發生改變。
4.4 一句話總結:
hash 計算與整個項目的構建相關;
chunkhash 計算與同一 chunk 內容相關;
contenthash 計算與文件內容本身相關。
最後推薦一下我的個人公眾號:「滷蛋實驗室」,平時會分享一些前端技術和數據分析的內容,大家感興趣的話可以關註一波: