webpack中的hash、chunkhash、contenthash區別

參考:medium.com/@okonetchni…css

hash、chunkhash、contenthash

  hash通常是結合CDN緩存來使用,經過webpack構建以後,生成對應文件名自動帶上對應的MD5值。若是文件內容改變的話,那麼對應文件哈希值也會改變,對應的HTML引用的URL地址也會改變,觸發CDN服務器從源服務器上拉取對應數據,進而更新本地緩存。可是在實際使用的時候,這幾種hash計算仍是有必定區別。jquery

咱們先建一個測試案例來模擬下:webpack

  • 項目結構web

    咱們的項目結構很簡單,入口文件index.js,引用了index.css。而後新建了jquery.js和test.js做爲公共庫。緩存

    //index.js
    
      require('./index.css')
      module.exports = function(){
      	console.log(`I'm jack`)
      	var a = 12
      }
    
    
      //index.css
    
      .selected : {
          display: flex;
          transition: all .6s;
          user-select: none;
          background: linear-gradient(to bottom, white, black);
      }
    複製代碼

接着咱們修改webpack.config.js來模擬不一樣hash計算服務器

  • hash測試

    hash是跟整個項目的構建相關,只要項目裏有文件更改,整個項目構建的hash值都會更改,而且所有文件都共用相同的hash值flex

    var extractTextPlugin = require('extract-text-webpack-plugin'),
      	path = require('path')
      
      module.exports = {
      	context : path.join(__dirname,'src'),
      	entry:{
      		main: './index.js',
      		vender:['./jquery.js','./test.js']
      	},
      	module:{
      		rules:[{
      			test:/\.css$/,
      			use: extractTextPlugin.extract({
      				fallback:'style-loader',
      				use:'css-loader'
      			})
      		}]
      	},
      	output:{
      		path:path.join(__dirname, '/dist/js'),
      		filename: 'bundle.[name].[hash].js',
      	},
      	plugins:[
      		new extractTextPlugin('../css/bundle.[name].[hash].css')
      	]
      }
    複製代碼

    根據上面的配置,咱們執行webpack命令以後,能夠獲得下面的結果ui

    採用hash計算的執行結果1:spa

執行結果2:
複製代碼

咱們能夠看到構建生成的文件hash值都是同樣的,因此hash計算是跟整個項目的構建相關,同一次構建過程當中生成的哈希都是同樣的
複製代碼
  • chunkhash

    採用hash計算的話,每一次構建後生成的哈希值都不同,即便文件內容壓根沒有改變。這樣子是沒辦法實現緩存效果,咱們須要換另外一種哈希值計算方式,即chunkhash。

    chunkhash和hash不同,它根據不一樣的入口文件(Entry)進行依賴文件解析、構建對應的chunk,生成對應的哈希值。咱們在生產環境裏把一些公共庫和程序入口文件區分開,單獨打包構建,接着咱們採用chunkhash的方式生成哈希值,那麼只要咱們不改動公共庫的代碼,就能夠保證其哈希值不會受影響。

    var extractTextPlugin = require('extract-text-webpack-plugin'),
      	path = require('path')
      
      module.exports = {
      	...
      	...
      	output:{
      		path:path.join(__dirname, '/dist/js'),
      		filename: 'bundle.[name].[chunkhash].js',
      	},
      	plugins:[
      		new extractTextPlugin('../css/bundle.[name].[chunkhash].css')
      	]
      }
    複製代碼

    採用chunkhash計算的執行結果1:

執行結果2:
複製代碼

咱們能夠看到,因爲採用chunkhash,因此項目主入口文件Index.js及其對應的依賴文件Index.css因爲被打包在同一個模塊,因此共用相同的chunkhash,可是公共庫因爲是不一樣的模塊,因此有單獨的chunkhash。這樣子就保證了在線上構建的時候只要文件內容沒有更改就不會重複構建
複製代碼
  • contenthash

    在chunkhash的例子,咱們能夠看到因爲index.css被index.js引用了,因此共用相同的chunkhash值。可是這樣子有個問題,若是index.js更改了代碼,css文件就算內容沒有任何改變,因爲是該模塊發生了改變,致使css文件會重複構建。

    這個時候,咱們可使用extra-text-webpack-plugin裏的contenthash值,保證即便css文件所處的模塊裏就算其餘文件內容改變,只要css文件內容不變,那麼不會重複構建。

    var extractTextPlugin = require('extract-text-webpack-plugin'),
      	path = require('path')
      
      module.exports = {
      	...
      	...
      	output:{
      		path:path.join(__dirname, '/dist/js'),
      		filename: 'bundle.[name].[chunkhash].js',
      	},
      	plugins:[
      		new extractTextPlugin('../css/bundle.[name].[contenthash].css')
      	]
      }
    複製代碼

    採用contenthash計算的執行結果1:

執行結果2:
複製代碼

相關文章
相關標籤/搜索