【问题标题】:Cache busting with CRA React使用 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 主题,但没有人给出正确/简单的答案。

【问题讨论】:

    标签: reactjs caching react-redux 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 匹配是一个非常简单的过程。

    相关问题:

    【讨论】:

    • 感谢您在这里如此彻底,这是我的方案的最佳答案。如果其他人试图确保 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 服务器有关。缓存通常通过添加一组响应标头来控制,这些标头告诉您的浏览器和代理服务器如何缓存此网站。详情请见:stackoverflow.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 加载时显示(第二次刷新)

      希望这会有所帮助...

      【讨论】:

      猜你喜欢
      • 2019-10-14
      • 2019-07-17
      • 2021-10-16
      • 1970-01-01
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多