知人者智,自知者明,胜人者有力,自胜者强。——老子
简介
在webpack
中有三种hash
可以配置,分别是hash
、chunkhash
、contenthash
他们是不对的可以针对不同的配置,首相要搞清楚这三种的hash
的区别,什么场景下,适合用哪种。
hash
所有文件哈希值相同,只要改变内容跟之前的不一致,所有哈希值都改变,没有做到缓存意义
chunkhash
当有多个chunk
,形成多个bundle
时,如果只有一个chunk
和一个bundle
内容变了,其他的bundle
的hash
都会发生变化,因为大家都是公用的一个hash
,这个时候chunkhash
的作用就出来了。它根据不同的入口文件(Entry)
进行依赖文件解析、构建对应的 chunk
,生成对应的哈希值。
contenthash
在打包的时候我们会在js
中导入css
文件,因为他们是同一个入口文件,如果我只改了js
得代码,但是他的css
抽取生成css
文件时候hash
也会跟着变换。这个时候contenthash
的作用就出来了。
下面直接用代码验证上面的猜想。
一个简单的 webpack 配置
我们现在就只创建一个能编译js
的webpack
配置,步骤如下:
- 创建一个空文件加,并且在当文件夹中打开
bash or cmd
。 npm init -y
生成package.json
。- 如果你安装了
cnpm or yarn
就执行cnpm i webpack webpack-cli -D
, 安装webpack
的包。 - 创建
src
,在src
内部创建chunk0.js
、chunk1.js
、common.js
、index.js
、style.css
,并且编写内部代码 - 在项目根目录创建
webpack.config.js
- 直接在
cmd
中运行webpack
文件目录如下:
下面是代码
chunk0.js
1 | export default function add(a, b) { |
chunk1.js
1 | export default function flow() { |
common.js
1 | export default function commonJs() { |
index.js
1 | import add from './chunk0.js'; |
style.css
1 | body { |
webpack.config.js
1 | module.exports = { |
hash
我们直接运行webpack
,运行结果如下图所示:
只有一个 hash,所有文件的 hash 都是相同:
如果我们改变修改chunk1.js中的代码:
1 | export default function flow() { |
再运行 webpack 发现所有的 hash 都变化了,如下图所示:
对比发现他们的 hash 并不相同了,这个时候如果想修改了chunk1.js,index.js 不产生变化,就要用到 chunkhash。
chunkhash
- 第一步 我们先把webpack.config.js做一下修改
1 | module.exports = { |
- 第二步 我们运行
webpack
根据上面图片发下,两个chunk
的hash
并不相同了。
- 第三部 我们修改
chunk1.js
1 | export default function flow() { |
- 再运行
webpack
根据图片我们看到了chunk1.js
的hash
变化,而index.js
的hash
并没有变化,达到了我们预期的效果,对我们线上的缓存也是比较好的。
contenthash
但是当我们一个js
文件里面引用了一个css
文件,如果我么修改了css
文件内的内容,我们css
中的内容,会发发现这整个bundle
的hash
也会发生更新。
我们要引入css
,并且要把css
提出、压缩生成一个css
文件,就要借助一个webpack
的插件,叫做MiniCssExtractPlugin
,他可以帮我提取 css 到 css 文件,并且压缩 css。
- 第一步先安装
css-loader
、mini-css-extract-plugin
包
1 | cnpm install css-loader mini-css-extract-plugin -D |
- 第二步修改
webpack.config.js
如下
1 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 新增 |
- 第三步运行 webpack
看代码可以看到index.css
和index.js
的hash
是一样的。
- 第四步修改 style.css
1 | html { |
- 第五步运行 webpack
对比两次构建的hash
,发现只修改了style.css
的文件,引入他的index.js
确也更新了hash
,这个时候就需要contenthash
来发挥作用了。
- 第六步修改
webpack.config.js
并且运行 webpack
1 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 新增 |
看到他们直接 hash 就是不同的。
- 修改
common.js
,直接运行 webpack
1 | export default function commonJs() { |
看到修改 js 时我们的 css 文件的 hash 并没有变更。
注意,当使用
contenthash
时,如果修改 js 文件,css 文件的 hash 不会变化,但是修改 js 的文件,css 文件的 hash 也会变化。
总结
hash 所有文件哈希值相同;
chunkhash 根据不同的入口文件(Entry)进行依赖文件解析、构建对应的 chunk,生成对应的哈希值;
contenthash 计算与文件内容本身相关,主要用在 css 抽取 css 文件时。