React SPA强制加载新的JS版本(包括移动版)

时间:2017-10-30 13:51:07

标签: javascript reactjs caching

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

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

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

然后我尝试将它放在我的index.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

强制浏览器加载新脚本的其他任何解决方案?

由于

3 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

我相信缓存属性只会影响index.html而不是它的相关文件。要使用java脚本文件执行此操作,您必须在服务器端执行某些操作以将这些值写入响应头。您可以尝试将查询字符串添加到脚本的末尾,引用类似

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

并在每个版本中增加该版本号。

如果您感觉大胆,可以在文件名中添加ejecting。这需要{_ 3}}来自create-react-app的配置,并且不是一个可能的步骤。您还可以查看一个有点冒险的methods自定义webpack配置而不弹出。

答案 2 :(得分:0)

将此代码添加到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”,然后运行新的构建。这样,构建极有可能重新使用旧文件名。

构建完成后,将以下链接添加到service-worker.js:

self.skipWaiting();

这将迫使即使现有的服务程序仍在运行,新的服务程序也会被激活。

将以下标头添加到index.html和service-worker.js:

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