1. 程式人生 > >webpack中hash、chunkhash、contenthash區別

webpack中hash、chunkhash、contenthash區別

在webpack中有時需要使用hash來做靜態資源實現增量更新方案之一,檔名的hash值可以有三種hash生成方式,每一種都有不同應用場景,那麼三者有何區別呢?

hash

如果都使用hash的話,因為這是工程級別的,即每次修改任何一個檔案,所有檔名的hash至都將改變。所以一旦修改了任何一個檔案,整個專案的檔案快取都將失效。如:

可以從上圖清晰的看見每個壓縮後的檔案的hash值是一樣的,所以對於沒有改變的模組而言,這樣做顯然不恰當,因為快取失效了嘛。此時,chunkhash的用途隨之而來。

chunkhash

chunkhash根據不同的入口檔案(Entry)進行依賴檔案解析、構建對應的chunk,生成對應的雜湊值。在生產環境裡把一些公共庫和程式入口檔案區分開,單獨打包構建,接著我們採用chunkhash的方式生成雜湊值,那麼只要我們不改動公共庫的程式碼,就可以保證其雜湊值不會受影響。並且webpack4中支援了非同步import功能,固,chunkhash也作用於此,如下:

我們將各個模組的hash值 (除主幹檔案) 改為chunkhash,然後重新build一下,可得下圖:

我們可以清晰地看見每個chunk模組的hash是不一樣的了。

但是這樣又有一個問題,因為我們是將樣式作為模組import到JavaScript檔案中的,所以它們的chunkhash是一致的,如test1.js和test1.css:

這樣就會有個問題,只要對應css或則js改變,與其關聯的檔案hash值也會改變,但其內容並沒有改變呢,所以沒有達到快取意義。固contenthash的用途隨之而來。

contenthash

contenthash是針對檔案內容級別的,只有你自己模組的內容變了,那麼hash值才改變,所以我們可以通過contenthash解決上訴問題。如下:

contenthash表示由檔案內容產生的hash值,內容不同產生的contenthash值也不一樣。在專案中,通常做法是把專案中css都抽離出對應的css檔案來加以引用。

在這裡我用mini-css-extract-plugin替代了extract-text-webpack-plugin。

const miniCssExtractPlugin=require("mini-css-extract-plugin");

module.exports={
    module:{
        rules:[
            {
                test: /\.css$/,
                use:[
                    miniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new miniExtractPlugin({
            filename: 'main.[contenthash:7].css'
        })
    }
}