https://juejin.cn/post/6844903935812059144

知人者智,自知者明,胜人者有力,自胜者强。——老子

简介

在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配置,步骤如下:

  1. 创建一个空文件加,并且在当文件夹中打开 bash or cmd。
  2. npm init -y 生成package.json。
  3. 如果你安装了cnpm or yarn 就执行 cnpm i webpack webpack-cli -D, 安装webpack的包。
  4. 创建src,在src内部创建chunk0.js、chunk1.js、common.js、index.js、style.css,并且编写内部代码
  5. 在项目根目录创建 webpack.config.js
  6. 直接在cmd中运行 webpack

    根据上面图片发下,两个chunk的hash并不相同了。 看到他们直接hash就是不同的。
    文件目录如下:
    webpack中的hash、chunkhash、contenthash分别是什么 - 图1
    下面是代码 chunk0.js
    export default function add (a, b) { return a + b; }; 复制代码
    chunk1.js
    export default function flow () { return ‘flow’; }; 复制代码
    common.js
    export default function commonJs () { return ‘commonJs’; }; 复制代码
    index.js
    import add from ‘./chunk0.js’; import commonJs from ‘./common’; console.log(add(1, 2)); console.log(commonJs()); 复制代码
    style.css
    body { background: #000; } 复制代码
    webpack.config.js
    module.exports = { mode: “production”, // 如果不添加就会警告 entry: { index: “./src/index.js”, // 一个入口文件 chunk1: “./src/chunk1.js” // 两一个入口文件 }, output: { filename: “[name].[hash].js” // 出口文件 } } 复制代码

    hash

    我们直接运行webpack,运行结果如下图所示:
    只有一个hash,所有文件的hash都是相同:
    webpack中的hash、chunkhash、contenthash分别是什么 - 图2
    如果我们改变修改chunk1.js中的代码:
    export default function flow () { return ‘flow1’; // flow => folw1 }; 复制代码
    再运行webpack发现所有的hash都变化了,如下图所示:
    webpack中的hash、chunkhash、contenthash分别是什么 - 图3
    webpack中的hash、chunkhash、contenthash分别是什么 - 图4
    对比发现他们的hash并不相同了,这个时候如果想修改了chunk1.js,index.js不产生变化,就要用到chunkhash。

    chunkhash

  • 第一步 我们先把webpack.config.js做一下修改

module.exports = { mode: “production”, entry: { index: “./src/index.js”, chunk1: “./src/chunk1.js” }, output: { filename: “[name].[chunkhash].js” // hash => chunkhash } } 复制代码

  • 第二步 我们运行webpack

webpack中的hash、chunkhash、contenthash分别是什么 - 图5

  • 第三部 我们修改 chunk1.js

export default function flow () { return ‘flow11111’; // flow1 => flow11111 }; 复制代码

  • 再运行webpack

webpack中的hash、chunkhash、contenthash分别是什么 - 图6
webpack中的hash、chunkhash、contenthash分别是什么 - 图7
根据图片我们看到了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包

cnpm install css-loader mini-css-extract-plugin -D 复制代码

  • 第二步修改webpack.config.js 如下

const MiniCssExtractPlugin = require(“mini-css-extract-plugin”); // 新增 module.exports = { mode: “production”, entry: { index: “./src/index.js”, chunk1: “./src/chunk1.js” }, output: { filename: “[name].[chunkhash].js” }, module: { // 新增 rules: [ { test: /.css$/, use: [ MiniCssExtractPlugin.loader, “css-loader” ] } ] }, plugins: [ // 新增 // 提取css插件 new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: “[name].[chunkhash].css” }) ] }; 复制代码

  • 第三步运行webpack

webpack中的hash、chunkhash、contenthash分别是什么 - 图8
看代码可以看到index.css和index.js的hash是一样的。

  • 第四步修改style.css

html { font-size: 13px; } 复制代码

  • 第五步运行webpack

webpack中的hash、chunkhash、contenthash分别是什么 - 图9
webpack中的hash、chunkhash、contenthash分别是什么 - 图10
对比两次构建的hash,发现只修改了style.css的文件,引入他的index.js确也更新了hash,这个时候就需要contenthash来发挥作用了。

  • 第六步修改webpack.config.js 并且运行 webpack

const MiniCssExtractPlugin = require(“mini-css-extract-plugin”); // 新增 module.exports = { mode: “production”, entry: { index: “./src/index.js”, chunk1: “./src/chunk1.js” }, output: { filename: “[name].[chunkhash].js” }, module: { // 新增 rules: [ { test: /.css$/, use: [ MiniCssExtractPlugin.loader, “css-loader” ] } ] }, plugins: [ // 新增 // 提取css插件 new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: “[name].[contenthash].css” }) ] }; 复制代码
webpack中的hash、chunkhash、contenthash分别是什么 - 图11

  • 修改common.js,直接运行webpack

export default function commonJs () { return ‘commonJs1’; }; 复制代码
webpack中的hash、chunkhash、contenthash分别是什么 - 图12
webpack中的hash、chunkhash、contenthash分别是什么 - 图13
看到修改js时我们的css文件的hash并没有变更。
注意,当使用contenthash时,如果修改js文件,css文件的hash不会变化,但是修改js的文件,css文件的hash也会变化。

总结

hash 所有文件哈希值相同;chunkhash 根据不同的入口文件(Entry)进行依赖文件解析、构建对应的 chunk,生成对应的哈希值;contenthash 计算与文件内容本身相关,主要用在css抽取css文件时。

参考

面试必备!webpack 中那些最易混淆的 5 个知识点
blackdous biu biu ~ @ blackdous 发布了 42 篇文章 · 获得点赞 614 · 获得阅读 69,029 关注
前端
文章分类
文章标签
Webpack
安装掘金浏览器插件
打开新标签页发现好内容,掘金、GitHub、Dribbble、ProductHunt 等站点内容轻松获取。快来安装掘金浏览器插件获取高质量内容吧!

webpack中的hash、chunkhash、contenthash分别是什么 - 图14
千钧
程序员
文章内容不错,点赞webpack中的hash、chunkhash、contenthash分别是什么 - 图15,建议作者再把错别字和文章的不通顺地方再优化下就更好啦
9月前
· 删除
1
回复
webpack中的hash、chunkhash、contenthash分别是什么 - 图16
nobody7341
注意,当使用contenthash时,如果修改js文件,css文件的hash不会变化,但是修改js的文件,css文件的hash也会变化。 最后这句话有点问题
1年前
· 删除
2
回复
webpack中的hash、chunkhash、contenthash分别是什么 - 图17
飘飞的夏秋
小前端
contenthash这一小节,应该补充下需要在index.js文件引入style.css
1年前
· 删除
1
回复


作者:blackdous
链接:https://juejin.cn/post/6844903935812059144
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。