【问题标题】:What is the purpose of webpack [hash] and [chunkhash]?webpack [hash] 和 [chunkhash] 的目的是什么?
【发布时间】:2016-02-03 12:00:27
【问题描述】:

谁能告诉我 [hash] 和 [chunkhash] 的目的是什么,它们来自哪里?

output: {
    path: "/home/proj/cdn/assets/[hash]",
    publicPath: "http://cdn.example.com/assets/[hash]/"
} 

【问题讨论】:

  • 是的,但仍然不清楚它是为什么而构建的
  • hm...here 也是一个非常有趣的话题。可能对你来说很容易理解
  • @StepanSuvorov 我相信你已经弄清楚了,但也许我的回答可以帮助其他人理解这一点。

标签: javascript webpack


【解决方案1】:

这个对我来说有一段时间不明显,所以我认为它值得更详细的解释。

官方文档是怎么说的:

来自官方documentation的简要说明他们的目的:

确保浏览器拾取更改文件的一种简单方法是使用 output.filename 替换。 [hash] 替换可用于 在文件名中包含特定于构建的哈希,但它甚至是 最好使用 [contenthash] 替换,它是 文件的内容,每个资产都不同。

另一个解释来自output.filenamedocumentation

  • [hash] 是“为每个构建生成的唯一哈希”
  • [chunkhash] 是“基于每个块的内容”
  • [contenthash] 是“为提取的内容生成的”

让我们通过示例使其更易于理解:

我的src 目录中有 3 个文件:index.jsindex.cssvendors.js

我的示例 Webpack 配置中的相关部分:
(不是完整的工作配置!)

entry: {
  index: ["./src/index.js", "./src/index.css"],
  vendors: ["./src/vendors.js"]
},
output: {
  filename: "[name].[hash].js"
}
plugins: [
  new MiniCssExtractPlugin({
    filename: "[name].[hash].css"
  })
]

所以我有 2 个块名称,indexvendors,但请注意 index 块也将具有 css 内容,因为它在数组中导入了一个 css 文件。构建时,css 部分将使用 MiniCssExtractPlugin (在我的情况下)导出到单独的文件,但 Webpack 知道 index.jsindex.css 属于同一个块。

现在让我们尝试使用不同的散列类型来构建它。 (同样更改两个filename 选项)

使用 [hash]:

每个文件都有相同的哈希值,因为[hash] 是根据我们所有使用过的源文件生成的。如果我在不更改任何内容的情况下重新运行构建,生成的哈希将保持不变。如果我只编辑一个文件,那么哈希值将会改变,并且我生成的所有捆绑包的名称中都会包含这个新的哈希值。

使用 [chunkhash]:

如您所见,第一个和第二个文件来自同一个 index 块,因此它们的名称中具有相同的哈希值。这是因为[chunkhash] 是根据给定块的全部内容生成的。因此,如果我编辑index.css 并重新构建,来自index 块的文件将有一个新的哈希值,但来自vendors 块的文件将保持与以前相同。

使用 [contenthash]:

这个很明显。每个生成的文件在其名称中都有一个唯一的哈希值,该哈希值是根据该文件的内容计算得出的。如果我改变假设index.css 重新构建,则只有生成的index.css 会有新的哈希。

【讨论】:

  • 由于我使用的是哈希,我的用户总是会得到应用程序的更新版本,但缺点是除非按下 Ctrl+F5,否则当应用程序被代码拆分时,用户可能最终会出现控制台错误它正在尝试动态提取具有旧版本/哈希的 JS 文件(显然不再存在)。是否有任何最佳实践解决方法?
  • 我认为最好的做法是在推送新代码并为index.html 等非静态文件指定Cache-Control: no-cache 之前不要清空您的公用文件夹。
  • @szegheo 您需要始终对 main.js 文件进行突发缓存。因此,每当任何块发生变化时,您肯定需要将版本控制添加到主 js 文件中。例如main.js?v=new1.2
【解决方案2】:

基本上它与浏览器缓存有关 - 当您提供资产时,您通常希望告诉客户端/浏览器他们可以使用相同的脚本/样式表/jpeg 等,而不必每次都下载它。这是通过发送适当的 HTTP 标头字段来完成的。

那么问题是你应该告诉客户他们可以继续使用相同的样式表多久?如果您重新设计您的网站并且他们不下载您的新样式表,他们将不会看到这些更改。解决方案通常是在样式表文件名中添加某种标识符或版本号 - 如果样式表更改时此 id/版本更改(因此文件名不同),浏览器将再次下载它(这称为缓存破坏)。

基本上,webpack 可以为 bundle 输出名称添加一个哈希,作为 bundle 内容的一个函数,当内容更改时会有所不同 - 从而使过程自动化。 chunkhash 如果您将捆绑包拆分为多个块,则会执行相同的操作。

这里有一些与 webpack 无关的讨论:Strategies for Cache-Busting CSS

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-10
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多