【问题标题】:Busting browser cache using React and Node使用 React 和 Node 破坏浏览器缓存
【发布时间】:2020-02-26 05:14:50
【问题描述】:

我有一个 React 应用程序,每次我重新部署时,用户都告诉我他们看不到更改。我要求他们进行硬重置并清除缓存。我想在推送新版本时破坏浏览器缓存,以便用户看到更改。

我最初使用 react-create-app 来创建应用程序。

我读到 here 你应该在你的 webpack 插件中使用 hash: true 。我这样做了,现在我看到捆绑的反应应用程序现在有一个查询字符串,但现在我收到错误:

Refused to execute script from 'https://example.com/static/js/main.9b80cc8a.js?76de7bb1d01e56c5fcb0' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled 

该错误已用 Node.js here 覆盖。我正在使用 express.static

我从这里更改了 web 包:

new HtmlWebpackPlugin({
  inject: true,
  template: paths.appHtml,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeRedundantAttributes: true,
    useShortDoctype: true,
    removeEmptyAttributes: true,
    removeStyleLinkTypeAttributes: true,
    keepClosingSlash: true,
    minifyJS: true,
    minifyCSS: true,
    minifyURLs: true,
  },
}),

到这里:

new HtmlWebpackPlugin({
  hash: true,
  inject: true,
  template: paths.appHtml,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeRedundantAttributes: true,
    useShortDoctype: true,
    removeEmptyAttributes: true,
    removeStyleLinkTypeAttributes: true,
    keepClosingSlash: true,
    minifyJS: true,
    minifyCSS: true,
    minifyURLs: true,
  },
}),

我的节点代码是这样的,我觉得是对的:

app.use(express.static(path.join(__dirname, 'public')));

公共目录包含生产构建的应用程序。

如何在应用更新时防止出现此错误并清除浏览器缓存?

【问题讨论】:

    标签: node.js reactjs caching webpack


    【解决方案1】:

    我更愿意发表评论,但我没有足够的声誉:p.

    我们为不同类型的应用程序设置了类似的设置。每次我们运行构建时,新包的哈希都会添加到 HTML 中脚本标记的源中。这是我们的HtmlWebpackPlugin 配置。

    new HtmlWebpackPlugin({
      inject: false,
      hash: true,
      template: '../runner.html',
      filename: 'index.html',
    }),
    

    我们的设置之间的主要区别是 inject 在我的设置中设置为 false。我们不想将整个 js 构建注入到 html 中。

    这里是../runner.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Spec Runner v3.1.0</title>
        <!-- include spec files here... -->
    
        <script src="<%= htmlWebpackPlugin.files.chunks.spec.entry %>"></script>
      </head>
      <body> 
      </body>
    </html>
    

    通知&lt;%= htmlWebpackPlugin.files.chunks.ENTER-THE-CHUNK-NAME.entry %&gt; 。这基本上告诉 webpack 将散列注入页面。这允许我们将更新直接包含到 html 页面中。当然,您仍然需要担心 html 页面的缓存时间。

    另外,如果您决定这样做,您将需要另一个插件来缩小您的代码。我推荐uglifyjs。文档可以帮助您指明正确的方向。

    【讨论】:

    • 我会给你一些声誉;)我使用创建反应应用程序,所以 webpack 构建在我的节点模块中。
    • 谢谢:)。此外,我在这里和那里使用了 create-react-app,当我运行 npm run build 时,它会创建一个 ./build 目录。问题,您是否创建了自己的 webpack 文件?
    • 不,它在节点模块中带有自己的 webpack 文件。它相当全面。我想如果我想自定义它,我可以将它从 node_modules 中删除并放在根目录中。 CRA 还创建了一个服务工作者,我最终对其进行了修改以使其正常工作。我会尽快发布答案。
    【解决方案2】:

    我最终放弃了 webpack 配置并修改了 service worker。

    如果有新内容可用,我修改了一个重新加载窗口的功能。您可以提示用户查看他们是否真的要重新加载(window.confirm),但在我的情况下,他们需要更新。

    function registerValidSW(swUrl) {
      navigator.serviceWorker
        .register(swUrl)
        .then(registration => {
          registration.onupdatefound = () => {
            const installingWorker = registration.installing;
            installingWorker.onstatechange = () => {
              if (installingWorker.state === 'installed') {
                if (navigator.serviceWorker.controller) {
                  // At this point, the old content will have been purged and
                  // the fresh content will have been added to the cache.
                  // It's the perfect time to display a "New content is
                  // available; please refresh." message in your web app.
                  window.location.reload(true); //**** THIS IS WHAT I CHANGED
                  console.log('New content is available; please refresh.');
                } else {
                  // At this point, everything has been precached.
                  // It's the perfect time to display a
                  // "Content is cached for offline use." message.
                  console.log('Content is cached for offline use.');
                }
              }
            };
          };
        })
        .catch(error => {
          console.error('Error during service worker registration:', error);
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-08
      • 1970-01-01
      • 2018-09-02
      • 1970-01-01
      • 2019-12-10
      • 2018-06-15
      • 2018-08-22
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多