【问题标题】:caching issue with web application developed using reactjs & webpack使用 react js 和 webpack 开发的 Web 应用程序的缓存问题
【发布时间】:2016-07-28 15:10:09
【问题描述】:

我正在开发一个使用 reactjs 和 webpack 开发的 Web 应用程序。每次部署后,我们必须要求用户清除浏览器缓存并重新启动浏览器。我认为 javascript 包文件和 css 文件都被缓存在用户浏览器上。

我们如何强制浏览器不缓存这些文件或让它从服务器下载最新的文件。

<html>
  <head>
    <meta charset="utf-8">
    <title>My App</title>
            <link rel="stylesheet" href="styles.css" media="screen" charset="utf-8">
  </head>
  <body>
    <div id="app"></div>
    <script src="bundle.js"></script>
  </body>
</html>

【问题讨论】:

    标签: javascript caching reactjs webpack


    【解决方案1】:

    您可以使用html-webpack-plugin

    plugins: [
        new HtmlWebpackPlugin({
            hash: true
        })
    ]
    

    哈希:真 |如果为 true,则为 false,然后将唯一的 webpack 编译哈希附加到所有包含的脚本和 css 文件中。这对于缓存无效化很有用。

    【讨论】:

    • 感谢您的快速回复。对于文件bundle.js?1c03629db68f03ac936e,我收到以下错误Failed to load resource: the server responded with a status of 404 (Not found)styles.css?1c03629db68f03ac936e 文件也会出现类似错误。我安装了 npm 包,并在 webapck 配置文件中简单地添加了您显示的代码。构建和部署后我收到错误。当我在本地运行应用程序时,出现以下错误 ncaught Invariant Violation: _registerComponent(...): Target container is not a DOM element.
    • 确保从 HtmlWebpackPlugin 生成的 html 文件正确引用了这些文件。我不知道您的项目是如何设置的,因此它可能会认为您的分发目录结构与实际不同。
    • 我认为问题是,查询字符串的格式不正确。而不是键值对,文件只是值。我的意思是,不是bundle.js?v=1c03629db68f03ac936e,而是bundle.js?1c03629db68f03ac936ekey 不见了。我错过了配置选项吗?
    • 这适用于 'webpack' 还是需要 'webpack-dev-server' ?
    • @stackdave 我认为它应该只适用于 webpack,它会在构建过程中进行哈希处理。
    【解决方案2】:

    有一个简单的方法可以避免这个问题而无需任何额外的东西。使用 webpack 内置的哈希能力。

    您可以阅读有关将哈希添加到捆绑包中的信息here。虽然这个标题是“长期缓存”,但它仅在您的文件没有更改的情况下才是正确的。但是如果你重建你的包,它会得到新的唯一哈希,所以浏览器会认为它是新文件并下载它。

    【讨论】:

    • 假设我在 webpack.config 文件中使用了filename: '[hash].bundle.js',。它会生成一个像 3d161aa1fedaca1ca95b.bundle 这样的文件。现在我如何更新我的 index.html 文件,它仍然包括像 &lt;script src="bundle.js"&gt;&lt;/script&gt; 这样的 bundle.js 文件。文章还说Note that you need to reference the entry chunk with its hash in your HTML. You may want to extract the hash or the filename from the stats.我在这里遗漏了什么吗?
    • 你可以在最后一章webpack.github.io/docs/…找到答案。构建后,您可以查看 stats.json 以查看实际的包名称,然后将其传递给您的 html 模板。
    • 感谢您的回复。我查看了assets-webpack-plugin,他们说This plug-in outputs a json file with the paths of the generated assets so you can find them from somewhere else.,但我没有看到解释他们如何更新index.html 中的参考文件名的示例
    • 哦,他们不更新 index.html。您可能应该使用一些模板引擎来生成 index.html 并将生成的资产作为变量传递给它。您的流程: 1. 使用 webpack 构建并获取 stats.json 2. 在启动服务器时读取 stats.json 3. 将正确的路径从 stats.json 传递到您的 html
    【解决方案3】:

    您应该使用带有模板 html 的 html-webpack-plugin 并将哈希配置放在输出中。所以你的 webpack 配置看起来像这样:

        output: {
            filename: "[name].[hash].js",
            path: <path to your bundle folder>
          }
         new HTMLWebpackPlugin({
              hash: true,
              template: paths.resolveFromRoot("src/index.html") //where you want the sample template to be
            })
    

    你的 index.html 会是这样的:

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="expires" content="0">
        <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>Title</title>
    </head>
    <body>
        <div id="app"></div>
    </body>
    </html>
    

    HTML webpack 插件会自动将修改后的脚本插入到你的 bundle 文件夹中创建的 index.html 中。希望这可以帮助。对于缓存修复,您可以参考https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching,其中提到了版本控制和服务器响应标头配置以实现有效的缓存解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-20
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      相关资源
      最近更新 更多