使用 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 清除缓存的主要内容,如果未能解决你的问题,请参考以下文章