如何在 Webpack 中使用 Cache-Busting?

How to use Cache-Busting with Webpack?

在使用 Webpack 之前,我总是依赖以下 "cache-busting" 模式:

<script src="foo.js?cacheBust=12345" />

其中 12345 是服务器在每次构建时为我生成的令牌(它可能是 Git 哈希,尽管在我的情况下它不是)。

有了 Webpack,我现在有两个文件:build.jschunk.1.js。由于我将第一个带入了普通的脚本标签,所以我可以使用上面的模式:

<script src="build.js?cacheBust=12345" />

然而,那时 build.js 去获取 chunk.1.js,并且当它获取时它不包括缓存破坏后缀。

我希望 Webpack 自动附加 ?cacheBust=12345,但我在构建时不知道 12345 部分,所以我无法将它包含在我的 [=19= 中].相反,我必须等到 HTML 页面被评估,此时我从服务器获取令牌。

所以,我的问题是,有没有办法让 Webpack 查看用于获取初始文件的参数(例如 ?cacheBust=12345)并在获取其他文件时附加相同的参数?

如果您想以“webpack 方式”实现缓存清除:

1。输出文件的哈希名称

将输出文件名更改为散列生成的名称(在构建阶段)

output: {
    path: '/',
    filename: '[hash].js',
    chunkFilename: '[chunkhash].js',
},

从那时起,您的 foo.jschunk.1.js 将被称为 e883ce503b831d4dde09.jsf900ab84da3ad9bd39cc.js。值得一提的是,此文件的生成通常与生产和时间有关,更新 cacheBust 值。

2。如何包含未知文件名?

从现在开始,您的 foo.js - 主文件以未知方式命名。要提取此文件名,您可以使用 AssetsPlugin

const AssetsPlugin = require('assets-webpack-plugin');
const assetsPluginInstance = new AssetsPlugin();

并将此插件添加到 webpack.config.js

plugins: [
    assetsPluginInstance
]

webpack-assets.json 文件中,您应该会看到类似

的内容
{
    "main": {
        "js": "/e883ce503b831d4dde09.js"
    }
}

您可以使用此文件指向主 .js 文件。有关详细信息,请阅读

3。受益时间

我猜如果你因为修改 chunk.2.js 文件而制作应用程序,你会从

更改文件路径
- build.js?cacheBust=12345
- chunk.1.js?cacheBust=12345
- chunk.2.js?cacheBust=12345
- chunk.2.js?cacheBust=12345

到新的

- build.js?cacheBust=12346   // modified referation to chunk.2.js file
- chunk.1.js?cacheBust=12346
- chunk.2.js?cacheBust=12346 // modified
- chunk.2.js?cacheBust=12346

如果您使用上述解决方案,您将获得免费缓存确定。现在 filles 将被称为

(之前的作品)

- e883ce503b831d4dde09.js
- f900ab84da3ad9bd39cc.js
- 5015cc82c7831915903f.js
- 8b6de52a46dd942a63a7.js

(新制作)

- c56322911935a8c9af13.js // modified referation to chunk.2.js file
- f900ab84da3ad9bd39cc.js
- cd2229826373edd7f3bc.js // modified
- 8b6de52a46dd942a63a7.js

现在只有 main filechunk.2.js名字有变化,你可以通过webpack的方式免费获得

您可以在此处阅读有关长期缓存的更多信息https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31

你可以简单地这样做

output: {
    filename: '[name].js?t=' + new Date().getTime(),
    chunkFilename: '[name]-chunk.js?t=' + new Date().getTime(),
    publicPath: './',
    path: path.resolve(__dirname, 'deploymentPackage')
}

你可以使用HtmlWebpackPlugin

来自webpack.js.org/plugins/html-webpack-plugin的描述:

... 插件简化了 HTML 文件的创建以服务于您的 webpack 包。这对于 在文件名中包含每次编译都会更改的散列的 webpack 包特别有用...

我的一部分webpack.config.js:

// ...
const HtmlWebpackPlugin = require('html-webpack-plugin');
// ...
module.exports = {
   // ...
   plugins: [
      new HtmlWebpackPlugin({
         template: './assets/index.html',
         hash: true,
      }),
      // ...
   ]
};

如果 hash: true 然后将唯一的 webpack 编译哈希附加到所有包含的脚本和 CSS 文件。这对于清除缓存很有用。

更多关于 HtmlWebpackPlugin 选项 github.com/jantimon/html-webpack-plugin

多亏了这个选项,我得到了输出 html 文件:

<!DOCTYPE html>
<html>
   <head>
      <!-- ... rest of my head code ... -->
      <link href="./css/styles.css?f42fdf96e2f7f678f9da" rel="stylesheet">
   </head>
   <body>
      <!-- ... rest of my body code ... -->
      <script type="text/javascript" src="./js/index.bundle.js?f42fdf96e2f7f678f9da"></script>
   </body>
</html>

我的项目源代码:github.com/cichy380/html-starter-bs4-webpack

有很多方法可以清除缓存,也可以使用 webpack。我自己经常使用后缀技术并来到这个 post 寻找答案。我使用的块与 OP 不同,因为我只引用 javascript 中运行 webpack 的块:

const componentPromise = import(/* webpackChunkName: "myDelayedSource" */ "path/to/myComponent/myComponent.js");

我找到的缓存清除(在 js 中)的解决方案是简单地更改块的名称:

const componentPromise = import(/* webpackChunkName: "myDelayedSource_2020-05-14" */ "path/to/myComponent/myComponent.js");

这不会给出文件后缀,但会更改文件名,引用该文件的脚本也会使用新文件名。

希望对大家有所帮助。

如果你想在 Webpack 中使用 name.js?cacheBust=1234 格式的散列,你可以这样做:

output: {
  filename: '[name].js',
  chunkFilename: '[name].js?cacheBust=[chunkhash]',
},

我正在使用 Laraval Mix 在 Webpack 中做一些非常相似的事情,我在这个 Github 问题中找到了答案:https://github.com/JeffreyWay/laravel-mix/issues/2131.

以下为 Webpack v5

webpack.config.js

module.exports = {
    // ...
    output: {
        filename: "[name].bundle.[chunkhash].js",
        path: path.resolve(__dirname, "dist"),
        assetModuleFilename: "images/[hash][ext][query]"
    },
    // ...
    optimization: {
        moduleIds: "deterministic",
    }
    // ...
}

使用散列很重要,例如 [chunkhash]

注意,方法不止一种。

来源:https://webpack.js.org/guides/caching/