webpack中的hash、chunkhash和contenthash

這三個hash值都是webpack在打包的時候根據內部算法生成的一串字符串,總的來說最大的不同就是其囊括控制的範圍大小不同,對應的控制顆粒度不同。

hash

hash是對webpack整個一次構建而言,在webpack構建中,文件都會帶上對應的MD5值,構建生成的文件hash值都是一樣的。如果出口是hash,那麼一旦針對項目中任何一個文件的修改,都會構建整個項目,重新獲取hash值。如果有目的性的緩存就會失敗。

chunkhash

chunkhash的範圍可以針對某個模塊而言,它會從入口出發,對依賴文件進行解析,構建對應的chunk和hash值。一般的使用是在生產環境對公共庫和程序入口文件單獨抽離開,單獨打包構建,用chunkhash的方式對這些打包後的文件帶上相應hash值。在線上,只要公共庫和入口沒變,其hash值就不會改變,從而達到緩存的目的。

eg:

entry:{
    main: path.join(__dirname,'./main.js'),
    vendor: ['vue']
},
output:{
    path:path.join(__dirname,'./dist'),
    publicPath: '/dist/',
    filname: 'bundle.[chunkhash].js'
}

此時入口有兩個,main和vendor,此時的打包就會生成main和ventor兩個hash值,這兩個hash值是分別以main和vendor爲入口出髮根據依賴文件構建生成的chunk和hash值。(chunk可以理解爲入口+他依賴的文件構成的模塊)
在這裏插入圖片描述

contenthash

contenthash的範圍更具體和更小,即對某一個文件而言,在webpack中的用法一般是分離js和css,單對css文件來設置。因爲上面的chunkhash存在一個問題:

chunkhash以入口和依賴文件構建的chunk模塊,只要對應其中一個css或則js改變,與其關聯的文件hash值也會改變,但其他內容並沒有改變,一定意義上的緩存也就失效。
比如我js文件邏輯改變了,但是我css樣式並沒有改動,css文件就應該從緩存中加載,不應該從服務器中重新獲取,浪費帶寬和性能。

所以在項目中,通常做法是把項目中css都抽離出對應的css文件來加以引用。

比如使用mini-css-extract-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'
        })
    }
}

在這裏插入圖片描述
main模塊用了chunkhash,這裏單獨把main的css抽離出來用contenhash處理,打包後即使css文件所處的模塊裏就算其他文件內容改變,只要css文件內容不變,那麼就不會重複構建。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章