Webpack 4:hash 和 contenthash 和 chunkhash,什么时候使用哪个?

Lit*_*lee 8 webpack

有人提出了与此类似的问题,但它仅解释了这些哈希值之间的差异。

但是,我仍然不知道我应该[hash][contenthash]什么时候选择而不是?有人可以告诉我一个示例情况吗?

=== 以前的身体 ===

webpack 文档解释了不同的哈希类型如下:

https://webpack.js.org/configuration/output/#outputfilename

哈希:

为每个构建生成的唯一哈希

内容哈希:

为提取的内容生成哈希

大块哈希:

基于每个块的内容的哈希:

我仍然对何时使用哪种类型的哈希感到困惑。

[hash] 为每个构建生成,但是在使用以下配置多次运行 webpack build 之后,我没有发现我的哈希值发生了变化。

module.exports = {
  output: {
    filename: '[name].[hash].js'
  }
}
Run Code Online (Sandbox Code Playgroud)

Webpack 版本 4.41.2

我还发现里面的 webpack 配置react-scripts 对 js 和 css 文件使用 contenthash,但对图像等资产文件使用 hash,这也令人困惑,他们为什么这样做,是[hash]二进制文件的更好选择吗?

Ind*_*ith 15

假设您有三个生成的包:

main.js
main.css
vendor.js
Run Code Online (Sandbox Code Playgroud)

main.js 文件中引用的 main.css。

哈希:

将为每个构建生成哈希数。对于所有捆绑文件,生成的哈希数将相同。

例如:

Hash: 66e665r76798c278ytr6

Generated Files:
main.66e665r76798c278ytr6.js
main.66e665r76798c278ytr6.css
vendor.66e665r76798c278ytr6.js
Run Code Online (Sandbox Code Playgroud)

所有三个文件都将包含相同的哈希数。只要您没有更改文件的任何内容,此哈希值就会相同。即使您在不更改任何内容的情况下运行许多构建,哈希数也将相同。

块哈希:

在这种情况下,将根据入口点生成哈希数,并且所有文件的哈希数都不同。

Hash: 66e665r76798c278ytr6

Generated Files:
main.77e665r76798c278ytr6.js
main.78e665r76798c278ytr6.css
vendor.79e665r76798c278ytr6.js
Run Code Online (Sandbox Code Playgroud)

如果您没有更改供应商文件,则生成的供应商文件的哈希值将相同。但是如果你添加任何新的供应商,哈希数将会改变。

如果您在 main.js 中进行了任何更改,则 main.js 和 main.css 都将具有新的哈希数,因为哈希数是根据入口点更改的。

内容哈希:

仅当您对特定文件进行任何更改时才会生成哈希,并且每个文件都将具有唯一的编号。

例如,如果您只更改了 main.js 文件,则只会为更改后的文件生成新的哈希,其他两个哈希将与之前的构建相同

Chunkash 和 ContentHash 都为每个生成的文件生成哈希数。唯一的区别是 ChunkHash 基于入口点生成哈希。

在大多数情况下,您将使用 ContentHash 进行生产。

借助 contenthash,您可以在浏览器中实现长期缓存。只要哈希值保持不变,浏览器就会为缓存的文件提供服务。

https://github.com/webpack/webpack.js.org/issues/2096

长期缓存: 为了缩短应用加载时间,我们经常使用缓存。在应用程序的初始加载期间,我们可以将资产的标头设置为 Cache-Control:max-age=31536000。之后,浏览器将缓存资产,随后的请求将从缓存中提供。

没有散​​列:

考虑到您对某些资产(例如 main.js)进行了更改,因为您已将 max-age 指定为 31536000,新的更改将不会得到反映,浏览器将继续从缓存中提供服务。

使用哈希:

为了覆盖这一点,我们在所有文件中使用哈希。如果您对文件进行了任何更改,则会生成新的哈希值,浏览器会将其视为新请求。

例子:

您仅在 main.js 中进行了更改。在 [hash] 的情况下,所有文件都将获得新的哈希数。浏览器会将这三个都视为新的,并发出三个新请求来获取文件

[contenthash] 不是这种情况。如果您提到 contenthash,那么只会更改 main.js 哈希。其他两个文件将具有相同的哈希值,并将继续从浏览器缓存中提供服务。

这将改善您的应用加载时间。

如果您需要实现长期缓存,那么建议使用 contenthash 而不是普通的 hash。

生成哈希值会增加应用程序编译时间。因此,您将在生产过程中使用 contenthash/hash。

有关长期缓存的更多信息:https : //developers.google.com/web/fundamentals/performance/webpack/use-long-term-caching

  • 在 webpack 5 中,“hash”已被弃用,现在您唯一的选择是使用“contenthash” (3认同)
  • 很好的解释,但 @Littlee 的主要问题的回答是“但是,我仍然不知道什么时候应该选择 [hash] 而不是 [contenthash]?” 有人可以给我展示一个示例情况吗?`仍然缺失。请也添加这一点。 (2认同)