使用 CRA React 清除缓存

Posted

技术标签:

【中文标题】使用 CRA React 清除缓存【英文标题】:Cache busting with CRA React 【发布时间】:2018-09-11 06:56:35 【问题描述】:

当我更新我的网站时,运行 npm run build 并将新文件上传到服务器,我仍在查看我网站的旧版本。

如果没有 React,我可以看到我的网站的新版本具有缓存清除功能。我这样做:

上一个文件

<link rel="stylesheet" href="/css/styles.css">

新建文件

<link rel="stylesheet" href="/css/styles.css?abcde">

我该如何做这样的事情或通过 create react app 实现缓存清除?

在 GitHub 中有很多关于此问题的 create react app 主题,但没有人给出正确/简单的答案。

【问题讨论】:

【参考方案1】:

正如这里之前的一些答案所提到的,在查看旧版本的 React 应用程序时,Service Worker 和(缺少)缓存标头都可能对你不利。

关于 caching,React 文档声明如下:

Cache-Control: max-age=31536000 用于您的build/static 资产,Cache-Control: no-cache 其他一切都是安全的 和有效的起点,确保您的用户的浏览器将 始终检查更新的index.html 文件,并将缓存所有 build/static 文件保存一年。请注意,您可以使用 build/static 安全年到期,因为文件内容 哈希嵌入到文件名中。

正如@squarism 所提到的,旧版本的 create-react-app 默认为 opt-out 服务工作者注册,而新版本是 opt-in。您可以在official docs 中阅读更多相关信息。如果您从旧版本的 create-react-app 开始并且想要切换到新的行为,那么将您的配置与最新的 template 匹配是一个非常简单的过程。

相关问题:

How to avoid caching for create-react-app ReactJS: How to prevent browser from caching static files? how to clear browser cache in reactjs

【讨论】:

感谢您在这里如此彻底,这是我的方案的最佳答案。如果其他人试图确保 Cloudfront 始终提供来自 S3 的最新应用程序,那么答案似乎是在网站存储桶中的 index.html 对象上配置 Cache-Control: max-age=0 @bszom 如何设置缓存控制:构建/静态与 index.html 的无缓存。元标记上是否有此属性? @A.com Cache-Control 是 HTTP 响应标头,与元标记无关。您如何配置它取决于您如何服务/托管您的应用程序。【参考方案2】:

编辑:create-react-app v2 现在默认禁用服务工作者

此答案仅适用于 CRA v1

这可能是因为你的网络工作者。

如果您查看 index.js 文件,您会看到

registerServiceWorker();

从来没有想过它做了什么?如果我们看一下它从中导入的文件,我们可以看到

// In production, we register a service worker to serve assets from local cache.

// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.

// To learn more about the benefits of this model, read URL
// This link also includes instructions on opting out of this behavior.

如果您想删除网络工作者,请不要只删除该行。导入 unregister 并在您的文件中调用它而不是 register。

import  unregister  from './registerServiceWorker';

然后调用

unregister()

附:注销时,至少需要刷新一次才能使其正常工作

【讨论】:

“至少需要一次刷新才能使其工作”您的意思是在第二次刷新后用户将能够看到新内容? @Alfrex92 是的。 有不同的解决方案吗?用户只需要刷新一次。 @AhmadMaleki 是的,如果您的项目没有部署,这是一个很好的解决方案,但是如果您的网站已经在线并且有人让服务人员工作;只需删除这些行就不会取消注册。【参考方案3】:

如果您的问题是在 index.html 中静态引用的资源,例如 .css 文件或其他 .js 文件(例如配置文件),您可以声明一个 React 环境变量,为其分配唯一值并在你的 index.html 文件。

在您的构建脚本 (bash) 中:

REACT_APP_CACHE_BUST=e.g. build number from a CI tool npm run build

在你的 index.html 中:

<link rel="stylesheet" href="%PUBLIC_URL%/index.css?cachebust=%REACT_APP_CACHE_BUST%" />

变量名必须以 REACT_APP_ 开头。更多关于 React 中的环境变量:https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables。

【讨论】:

我们的 javascript 代码和 HTML 代码怎么样,因为每当我上传新代码时,它们都不会被添加。? 抱歉回复晚了。我认为 javascript 的情况取决于您的构建过程。我们使用 create-react-app(package.json -> scripts -> build 条目是 'react-scripts build')。构建过程生成 javascript 文件,文件名包括文件内容的哈希。所以一般来说,我认为不需要对 js 文件进行额外的缓存清除。如果您的 index html 文件正在被缓存,那么问题可能出在 Web 服务器的缓存控制中。 感谢米哈尔的回复。 Michal,你能帮我如何处理 Web 服务器的缓存控制,因为我的 react 应用程序位于单独的服务器上,而 Express.js (Node.js) 服务器位于不同的服务器上。 如果我理解您的设置正确,您的问题可能与 React 应用程序 Web 服务器有关。缓存通常通过添加一组响应标头来控制,这些标头告诉您的浏览器和代理服务器如何缓存此网站。详情请见:***.com/questions/49547/…. 感谢您的详细回复,基本上每当我在部署最新代码后访问我的 react 应用程序时,我总是会看到我之前部署的 react 构建代码,直到我手动清除浏览器的缓存。这是我的主要问题。【参考方案4】:

对于服务人员,他们似乎从选择退出变为选择加入。这是更改自述文件的提交,其中包含类似于 Kerry G 的答案的示例:

https://github.com/facebook/create-react-app/commit/1b2813144b3b0e731d8f404a8169e6fa5916dde4#diff-4e6ec56f74ee42069aac401a4fe448ad

【讨论】:

【参考方案5】:

当我使用create-react-app(并部署到heroku)时,我遇到了同样的问题。它一直显示我的应用程序的旧版本?。

我发现问题似乎出在浏览器端,它缓存了我的旧 index.html 及其过时的 js 包

您可能希望将以下内容添加到服务器端响应标头中

"Cache-Control": "no-store, no-cache"

或者如果您也在使用 heroku create-react-app-buildpack,请更新 static.json 文件

"headers":  
    "/**":  
        "Cache-Control": "no-store, no-cache" 
     

我觉得这样你还是可以留住那个可怜的 service worker ?,最新的内容会在 N+1 加载时显示(第二次刷新)

希望这会有所帮助...

【讨论】:

您真的想对所有内容都进行无缓存吗?只是 html 文件是罪魁祸首吗? 也许这个更好github.com/heroku/heroku-buildpack-static#custom-headers

以上是关于使用 CRA React 清除缓存的主要内容,如果未能解决你的问题,请参考以下文章

text 清除React Native Project的缓存

React-Native清除缓存汇总

React-Native清除缓存汇总

React-Native清除缓存汇总

React-Native清除缓存汇总

React-Native清除缓存汇总