如何使用Service Worker处理index.html文件的缓存?

时间:2019-11-13 02:55:07

标签: javascript reactjs service-worker create-react-app

我目前正在使用create-react-app默认服务工作程序来开发渐进式Web应用。

发布新版JavaScript块之一时,我在清除缓存方面遇到问题。

构建时,输出的javascript文件使用contenthash来确保当JS文件中的内容更改时,文件名也更改。在没有服务工作者的情况下运行时,这可以成功清除缓存。

但是,在使用create-react-app服务工作者时,包括我的index.html文件在内的所有静态资产都会被缓存。这意味着将向用户提供旧的index.html,其中包括我的旧缓存javascript文件的<script>标记,而不是更新后的contenthash的新标记。 / p>

我已经弹出并修改了webpack.config.js WorkboxWebpackPlugin以排除我的index.html文件:

 new WorkboxWebpackPlugin.GenerateSW({
      clientsClaim: true,
      exclude: [/\.map$/, /asset-manifest\.json$/, /index.html/],
      importWorkboxFrom: "cdn",
      navigateFallbackBlacklist: [
          // Exclude URLs starting with /_, as they're likely an API call
             new RegExp("^/_"),
          // Exclude URLs containing a dot, as they're likely a resource in
          // public/ and not a SPA route
            new RegExp("/[^/]+\\.[^/]+$")
          ]
        }),

这似乎适当地停止了对我的索引文件的缓存,从而允许其在脚本标签中包含更新的main.[contenthash].js。但是,现在我知道我的PWA不能脱机工作,因为服务工作者不提供index.html文件,也不能从脱机连接中提供该文件。

处理此问题的最佳方法是什么?完全脱机访问不是必不可少,但很高兴,我想知道其他开发人员如何在不完全删除index.html的情况下处理索引文件的服务工作者缓存的“破坏”由服务工作者缓存?在包含内容散列的index.html重新标记中,它们是否具有更实用的功能来处理此更改?

谢谢

3 个答案:

答案 0 :(得分:0)

仅在生产环境中启用服务工作者,例如npm run build的输出。建议您不要在开发环境中启用脱机优先服务工作者,因为当使用先前缓存的资产并且不包括您在本地进行的最新更改时,这会导致失败。

来自-https://create-react-app.dev/docs/making-a-progressive-web-app/

答案 1 :(得分:0)

我研究了应用程序外壳体系结构,其中服务工作者缓存应用程序外壳并为后续请求返回它。对于缓存清除,我还对应用程序外壳进行了版本控制,例如appshell- [hash] .html,因此,下次更改哈希时,服务工作者将缓存并提供新的应用程序外壳,并丢弃旧的应用程序外壳。

答案 2 :(得分:0)

您可以使用的一种方法是使用“回退到缓存”缓存策略。本质上,当请求文档(例如 index.html 文件)时,您首先尝试通过转发获取请求从网络加载它。但是,如果获取请求失败(网络不可用),则您将从缓存中提供请求。当然,您还需要根据每个请求更新 index.html 的缓存副本以保留到新副本。

这样,如果网络可用 - 您将始终获得 index.html 的最新版本,否则,将从缓存中提供最新的已知版本。