React SPA 强制加载新的 JS 构建(包括移动)



我目前每次为生产构建脚本时都遇到,浏览器不会加载任何新的JS。

我正在使用create-react-app.使其工作的唯一方法是手动清除缓存。

我试图放window.location.reload(true)但它仍然无法获取最新的 JS。

然后我尝试将其放在我的索引中.html

<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />

他们都没有工作。

浏览器不会加载任何新的JS,特别是对于移动设备(Chrome Android,Firefox)。

我正在使用Cloudflare,我已经尝试purge cache

还有其他解决方案可以强制浏览器加载新脚本吗?

谢谢

一种常见的方法是在JS文件中放置一个唯一的哈希值,以便浏览器关闭并获取它认为与以前完全不同的文件。

如果您使用的是 Webpack(我假设您使用的是 create-react-app),那么您可以将[hash]添加到输出 JS 文件名中:

output: {
    filename: 'bundle.[hash].js',
},

将此代码添加到 registerServiceWorker.js。激活新的服务工作进程后,它将重新加载页面。我通常将其添加到 registerValidSW 函数中,如下所示:

    function registerValidSW(swUrl) {
    //Reload once the new service worker is activated.
      var refreshing;
      navigator.serviceWorker.addEventListener('controllerchange',
        function () {
          if (refreshing) return;
          refreshing = true;
          window.location.reload();
        }
      );

//Below code is create-react-app default
      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.
                  console.log('New content is available; please refresh.');
                  // window.location.reload(true);
                } 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);
        });
    }

我注意到,对于create-react-app,通常连续的构建最终都以相同的哈希文件名结束。这导致应用程序重用旧的缓存文件。

为了解决这个问题,我将旧的构建目录重命名为"build.old",然后运行一个新的构建。这样,构建重用旧文件名的可能性非常小。

构建完成后,将以下链接添加到服务工作进程.js:

self.skipWaiting();

这将强制激活新的服务工作线程,即使现有服务工作线程仍在运行。

将以下标题添加到索引.html和服务工作者.js:

cache-control: max-age=0,no-cache,no-store,must-revalidate
我相信

缓存属性只会影响索引.html而不是它的依赖文件。 要使用java脚本文件执行此操作,您必须在服务器端执行一些操作,将这些值写入响应标头。 您可以尝试将查询字符串添加到脚本引用的末尾,如下所示

<script src='/dist/main.js?v=123'></script>

并随着每个版本增加该版本号。

如果你觉得大胆,你可以在文件名中添加哈希。 这需要从 create-react-app 中弹出您的配置,并且可能不是一个可以采取的步骤。您还可以研究一种有点棘手的方法,即在不弹出的情况下自定义 webpack 配置。

最新更新