简体   繁体   English

如何使用服务人员处理 index.html 文件的缓存?

[英]How to handle caching of index.html file with service worker?

I am currently working on a progressive web app using the create-react-app default service worker.我目前正在使用create-react-app默认服务工作者开发一个渐进式 web 应用程序。

I am having issues with busting the cache when releasing a new version of one of our javascript chunks.在发布我们的 javascript 块之一的新版本时,我遇到了破坏缓存的问题。

When building, the output javascript files use a contenthash to make sure that when content changes in the JS file, so does the file name.在构建时,output javascript 文件使用contenthash来确保当 JS 文件中的内容发生变化时,文件名也会发生变化。 This successfully busts the cache when running WITHOUT a service worker.在没有服务工作者的情况下运行时,这成功地破坏了缓存。

However, when using the create-react-app service worker, all static assets including my index.html file is cached.但是,当使用create-react-app service worker 时,包括我的index.html文件在内的所有 static 资产都会被缓存。 This means that the old index.html is being served to users, which includes a <script> tag to my old, cached javascript file(s) instead of the new one with the updated contenthash .这意味着旧index.html正在提供给用户,其中包含一个<script>标记到我的旧缓存 javascript 文件,而不是具有更新contenthash的新文件。

I have ejected and modified the webpack.config.js WorkboxWebpackPlugin to exclude my index.html file:我已经弹出并修改了 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("/[^/]+\\.[^/]+$")
          ]
        }),

And this seems to appropriately stop the caching of my index file, allowing it to include the updated main.[contenthash].js in its script tag.这似乎适当地停止了我的索引文件的缓存,允许它在其脚本标记中包含更新的main.[contenthash].js However, now I am aware that my PWA will not work offline as the index.html file is not served by the service worker and will not be served from an offline connection.但是,现在我知道我的 PWA 将无法脱机工作,因为 index.html 文件不是由 service worker 提供服务,也不会通过脱机连接提供服务。

What is the best way to handle this?处理这个问题的最佳方法是什么? Full offline access isn't essential but would be nice to have, and am wondering how other developers are handling the 'busting' of the service worker cache for their index file without fully removing index.html from being cached by the service worker?完全离线访问不是必需的,但会很好,并且想知道其他开发人员如何处理他们的索引文件的服务工作者缓存的“破坏”而不完全删除 index.html 被服务工作者缓存? Is there a more functional way to handle this change in the index.html regarding tags with content hashes?是否有更实用的方法来处理 index.html 关于带有内容哈希的标签的这种变化?

Thank you谢谢

I worked on an app shell architecture where the service worker caches the app shell and returns it for subsequent requests.我在一个应用程序 shell 架构上工作,其中服务人员缓存应用程序 shell 并将其返回给后续请求。 For Cache busting, I versioned the app shell also, like appshell-[hash].html, so next time when hash changes, the service worker will cache and serve the new app shell discarding the old one. For Cache busting, I versioned the app shell also, like appshell-[hash].html, so next time when hash changes, the service worker will cache and serve the new app shell discarding the old one.

One way you could make it work is by using the "fallback to cache" caching strategy.使其工作的一种方法是使用“回退到缓存”缓存策略。 Essentially, when document (eg index.html file) is requested you first try to load it from the network by forwarding the fetch request.本质上,当请求文档(例如index.html文件)时,您首先尝试通过转发获取请求从网络加载它。 However, if the fetch request fails (network is not available) you would then serve the request from the cache.但是,如果获取请求失败(网络不可用),您将从缓存中提供请求。 You will also need to update your cached copy of index.html of course with each request to preserve to fresh copy.当然,您还需要更新index.html的缓存副本,每个请求都保留为新副本。

This way, if the network is available — you will always get the fresh version of your index.html , if not, the latest known version will be served from the cache.这样,如果网络可用 - 您将始终获得index.html的新版本,如果没有,将从缓存中提供最新的已知版本。

If you used create-react-app with cra-template-pwa (npx create-react-app my-app --template cra-template-pwa) then you can filter out the index.html when you precache and then register index.html so that it's network first.如果您将 create-react-app 与 cra-template-pwa (npx create-react-app my-app --template cra-template-pwa) 一起使用,那么您可以在预缓存时过滤掉 index.html 然后注册 index. html 所以它是网络优先的。

import { NetworkFirst } from 'workbox-strategies'

// precacheAndRoute(self.__WB_MANIFEST)

const toPrecache = self.__WB_MANIFEST.filter(
  (file) => !file.url.includes('index.html'),
)

precacheAndRoute(toPrecache)

registerRoute(
  ({ url }) => url.pathname.includes('index.html'),
  new NetworkFirst(),
)

Then you need to remove the part where it routes all navigation requests to index.html然后您需要删除将所有导航请求路由到 index.html 的部分

// Set up App Shell-style routing, so that all navigation requests
// are fulfilled with your index.html shell. Learn more at
// https://developers.google.com/web/fundamentals/architecture/app-shell
// const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$')
// registerRoute(
//   // Return false to exempt requests from being fulfilled by index.html.
//   ({ request, url }) => {
//     // If this isn't a navigation, skip.
//     if (request.mode !== 'navigate') {
//       return false
//     } // If this is a URL that starts with /_, skip.

//     if (url.pathname.startsWith('/_')) {
//       return false
//     } // If this looks like a URL for a resource, because it contains // a file extension, skip.

//     if (url.pathname.match(fileExtensionRegexp)) {
//       return false
//     } // Return true to signal that we want to use the handler.

//     return true
//   },
//   createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html', true),
// )

The service worker is only enabled in the production environment, eg the output of npm run build. service worker 仅在生产环境中启用,例如 npm 运行构建的 output。 It's recommended that you do not enable an offline-first service worker in a development environment, as it can lead to frustration when previously cached assets are used and do not include the latest changes you've made locally.建议您不要在开发环境中启用离线优先服务工作者,因为当使用以前缓存的资产并且不包括您在本地所做的最新更改时,这可能会导致挫败感。

From -https://create-react-app.dev/docs/making-a-progressive-web-app/从 -https://create-react-app.dev/docs/making-a-progressive-web-app/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 服务人员未缓存HTML文件 - Service Worker not caching html file 在位于 SRC 文件夹中的 index.html 文件中注册 service-worker - ReactJS - Register a service-worker in index.html file that's located in SRC folder - ReactJS 服务工作者不会在&#39;/&#39;上缓存golang服务器提供的index.html - Service worker does not cache index.html served by golang server on '/' 我的服务工作者正在缓存诸如索引页之类的文本/html 文档,如何阻止它? - My service worker is caching text/html documents like index page, how to stop it? 如何将index.html中的变量传递给服务? - How to pass a variable in index.html to a service? 浏览器如何在单个页面应用程序上缓存index.html - How works browser caching for index.html on a single page application 服务人员错误的缓存文件 - service worker wrong caching file 服务工作者仅在添加“ index.html”时从缓存中获取URL。 - Service worker only fetches url from cache when adding “index.html” 从 create-react-app 中的 service worker 缓存中排除 index.html - exclude index.html from service worker cache in create-react-app index.js 文件如何与 index.html 通信? - How index.js file is able to communicate with index.html?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM