详解webpack中的hash、chunkhash、contenthash区别
hash、chunkhash、contenthash
hash一般是结合CDN缓存来使用,通过webpack构建之后,生成对应文件名自动带上对应的MD5值。如果文件内容改变的话,那么对应文件哈希值也会改变,对应的HTML引用的URL地址也会改变,触发CDN服务器从源服务器上拉取对应数据,进而更新本地缓存。但是在实际使用的时候,这几种hash计算还是有一定区别。
我们先建一个测试案例来模拟下:
项目结构
我们的项目结构很简单,入口文件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值
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命令之后,可以得到下面的结果
采用hash计算的执行结果1:

执行结果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:

详解webpack中的hash、chunkhash、contenthash区别的更多相关文章
- 详解HTTP中GET与POST的区别,不是你看过的标准答案!
防吐槽声明:本文适合程序员新人,自认阅文无数.技术超叼的大神不用看. GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含 ...
- 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发
每天记录一点:NetCore获得配置文件 appsettings.json 用NetCore做项目如果用EF ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...
- 详解Vue中的computed和watch
作者:小土豆 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.cn/user/2436173500265335 1. 前言 作为一名Vue ...
- 详解JavaScript中的原型
前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...
- jQuery:详解jQuery中的事件(二)
上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...
- 图文详解Unity3D中Material的Tiling和Offset是怎么回事
图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...
- 【转】详解C#中的反射
原帖链接点这里:详解C#中的反射 反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...
- 详解Webwork中Action 调用的方法
详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
随机推荐
- SQL语句(五)数据的修改
数据的修改 UPDATE 格式 UPDATE 表名 SET 字段名 = 字段值(这个可以是表达式) [WHERE 条件表达式] 关系运算符 (>.<.>=. <=.=.< ...
- 浅谈分词算法(3)基于字的分词方法(HMM)
目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...
- 15. Spring boot CRUD
一.列表页 templates/emp/list.html 0.侧边栏链接: <li class="nav-item"> <a class="nav-l ...
- rest framework错误笔记——AssertionError: Cannot apply DjangoModelPermissionsOrAnonReadOnly on a view that does not set `.queryset` or have a `.get_queryset()` method.
用到@api_view装饰器时,访问路由查看api数据时,报错: AssertionError: Cannot apply DjangoModelPermissionsOrAnonReadOnly o ...
- luogu P3576 [POI2014]MRO-Ant colony
传送门 一群蚂蚁能被吃,也就是走到指定边的两端点之一要走到另一端点时有\(k\)只,我们可以从这两端点逆推,记两个值为走到某个点时最后会被吃掉\(k\)只蚂蚁的蚂蚁数量范围,式子下面有,很好理解(雾) ...
- Spring+SpringMVC+Mybatis整合(二)
目录结构:
- 2017/05/03 java 基础 随笔
1.硬盘500G 厂商是按照1000计算的 500g=500*1000*1000/1024/1024=465g 2.jdk1.7可以表示二进制了 0b001(b大小写无所谓) 3.进制转换 4.原码, ...
- UML和模式应用5:细化阶段(9)---迈向对象设计
1.前言 开发者如何设计对象,可以采用如下三种方式: 编码:在编码的同时进行设计 绘图然后编码:绘制一些UML,然后转到如上编码方式,在集成开发环境中编码 只绘图,不编码:使用工具从图中生成一切 本章 ...
- SonarQube代码质量管理工具安装与使用(sonarqube5.1.2 + sonar-runner-dist-2.4 + MySQL5.x)
1. SonarQube安装(sonarqube5.1.2 + sonar-runner-dist-2.4) 1.1 前提条件 1) 已安装Java环境(version:1.7+) 2) 已安装MyS ...
- windows安装配置git和Tortoisegit
git github gitlab Tortoisegit 的概念自行百度 1. 安装git 2. 安装小乌龟:Tortoisegit 和中文包 3. 配置 4. 使用 参考: 目录 安装及配置 ...