新部署后,React应用必须清除浏览器缓存

时间:2020-05-15 07:30:29

标签: javascript reactjs apache caching deployment

我们正在使用Jenkins管道在Apache服务器上部署React应用程序。 当我们部署新代码时,大多数新功能都可以正常工作,但并非所有更改都反映了浏览器中的最新功能。用户必须打开隐身窗口或清除缓存才能查看新功能。

我看到了一些与angular applications相关的解决方案,但是任何与React应用程序相关的东西,我什么都看不到。 在构建期间,我们可以添加一些可以自动为最终用户提供最新更改的内容吗?我猜想,必须进行缓存清除,但是如上面的解决方案对Angular应用所做的那样,我们如何不做大量修改就可以做到。

4 个答案:

答案 0 :(得分:6)

通常的方法是根据时间或内容将哈希值添加到脚本和其他资产文件名中。因此,在您拥有script.js之前,现在是script.[contenthash].js。每次更改脚本的内容时,内容哈希将有所不同。

现在,当用户请求应用程序的index.html时,它将引用包含各个内容哈希的脚本。如果用户先前加载了script.abc123.js,而现在index.html引用了script.cba321.js,则浏览器将知道它以前没有看到此文件并进行加载。这样,用户即可获得脚本和其他资产(js,css,图像等)的当前版本。但是,要使此功能正常工作,重要的是用户必须始终加载index.html的最新版本。

此方法不是特定的反应,而是通用的方法和最佳实践。但是,create-react-app使用并建议使用它(请参阅:https://github.com/facebook/create-react-app)。

由于始终要手动执行此操作非常繁琐,因此有许多脚本和策略可用于使用模块捆绑程序来实现此目标。例如。通过使用WebPack:https://webpack.js.org/guides/caching/

还有其他方法,例如为脚本文件设置缓存响应标头,但是在这种情况下我不建议这样做。

答案 1 :(得分:2)

您必须配置服务器的缓存策略。

nginx示例:

location /{
     alias /www/your/app/;
     try_files $uri $uri/ /index.html;
     add_header Cache-Control "no-store, no-cache, must-revalidate";
}

您可以在这里https://medium.com/@pratheekhegde/setting-caching-headers-for-a-spa-in-nginx-eb2f75f52441

了解更多信息

答案 2 :(得分:1)

我在开发环境中亲自使用以下内容进行测试

# Never cache these...
# HTTP 1.1=>Cache-Control, HTTP 1.0=>pragma and Expires=>proxy

# for html,htm,json,js,css as follows
<filesMatch "\.(html|htm|json|js|css)$">
  FileETag None
  <ifModule mod_headers.c>
     Header unset ETag
     Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
     Header set Pragma "no-cache"
     Header set Expires "0"
  </ifModule>
</filesMatch>

服务器将ETag标头添加到包含正在提供的资源的响应中,客户端缓存该资源并记住其实体标签(ETag的值)。

另一种简单的方法是使用查询字符串,每次进行更改时都增加查询字符串,或者每进行更改时都使用一些唯一的字符串,如下所示。您无需更改apache配置浏览器即可加载相应的脚本。

# first version
<script src="path/to/your/app-loader.js?version=1"></script>

答案 3 :(得分:0)

我在 webpack 配置中使用 chunkhash 添加了时间。这解决了我在每次部署时使缓存无效的问题。此外,我们需要注意 index.html/asset.manifest 不会缓存在您的 CDN 或浏览器中。 webpack 配置中块名称的配置将如下所示:-

文件名:[chunkhash]-${Date.now()}.js

或者如果您使用的是 contenthash 则

文件名:[contenthash]-${Date.now()}.js