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:
复制代码

相关文章
相关标签/搜索