前言
作为前端开发者都会遇到一个问题: 前端代码发版后用户资源获取失败
。平时代码发布上线时,避免不了客户同时在使用中的情况。 那么解决这个问题的前提,我们需要来认识一下打包后产物的几种hash
关系。
下面我们拿常用的webpack
和vite
的打包工具来讲述。
主要的hash
方式
在webpack
中,主要的hash方式有三种, 分别是: hash
、 chunkhash
、contenthash
。
1.hash
模式
hash
模式: 底层是创建生成一个新的hash
实例,打包时,每个文件都同时写入同一个hash
值。而这种形式,相当于把所有代码资源都更新了,类似于全量更新
。
我们创建两个文件login.js
和home.js
, 分析它的打包情况。webpack.config.js
下配置输出的文件名为[name].[hash].js
。
执行build指令之后,可以看到home.js
和login.js
两个文件的hash
值是一样的,当你修改login.js
的文件后,再重新打包,他们的hash
值还是一样的。
上面这种就是hash
模式。修改其中一个文件,重新打包时,hash
值都一起更新为同一个新值。
2.chunkhash
模式
chunkhash
模式: 基于hash
模式进行改进,当前文件改变时,当前文件所引入的依赖和当前文件的hash
值都会重新生成一个新的hash值
。而其他未改变的内容的文件,或者和它们无依赖关系的文件,保持原有的hash
值。它可以说是一种局部更新
。 未更新的文件可以进行缓存的作用。
在login.js
和home.js
的文件的基础上,再创建一个register.js
文件。
login.js
引入register.js
的常量reg
:
它们未修改内容时,打包之后的文件如下:
修改register.js
的常量值改为reg = 123456
之后,相关依赖的文件会重新打包,而没有依赖的home.js
文件则被缓存。
以上就是chunkhash
模式。
3. contenthash
模式
contenthash
模式: contenthash
可以说是较好的一种hash
模式,它是在chunkhash
上再一次改良。当前文件的内容发生变化时,当前文件的hash
值才会重新生成。而涉及到的依赖的文件和其他文件没有改变内容的情况下,保持原有的hash值
。对long term cache
长期缓存很友好。这种行为类似于最小量更新
。
把webpack.config.js
下配置输出的文件名为[name].[contenthash].js
。
未修改文件内容的产物hash值
如下:
我们来修改一下register.js
文件,把常量修改为reg = null
之后:
修改之后,变化是login.js
,因为register.js
打包后的产物的reg常量
已经在login.js
文件内。所以相当于login.js
这个chunk
里面的内容发生了变化。
以上就是contenthash
模式。
小结
-
hash
模式: 底层是创建生成一个新的hash
实例,打包时,每个文件都同时写入同一个hash
值。而这种形式,相当于把所有代码资源都更新了,类似于全量更新
。 -
chunkhash
模式: 基于hash
模式进行改进,当前文件改变时,当前文件所引入的依赖和当前文件的hash
值都会重新生成一个新的hash值
。而其他未改变的内容的文件,或者和它们无依赖关系的文件,保持原有的hash
值。未更新的文件可以进行缓存的作用,它可以说是一种局部更新
。 -
contenthash
模式:contenthash
可以说是较好的一种hash
模式,它是在chunkhash
上再一次改良。当前文件的内容发生变化时,当前文件的hash
值才会重新生成。而涉及到的依赖的文件和其他文件没有改变内容的情况下,保持原有的hash值
。对long term cache
长期缓存很友好。这种行为类似于最小量更新
。