Javascript 我应该如何更新服务人员和缓存的PWA文件

Javascript 我应该如何更新服务人员和缓存的PWA文件,javascript,service-worker,progressive-web-apps,cdn,Javascript,Service Worker,Progressive Web Apps,Cdn,因此,在我当前的系统中,每当我创建一个javascript包时,我都会在文件名中添加一个哈希值,用于生产构建。我的index.html中没有CDN缓存,因此每当出现新的构建时,就会创建一个指向新的哈希javascript文件名的新index.html。无论何时发生新部署,这都能很好地使捆绑包的缓存失效(代价是我的非常小的index.html没有被缓存) 我想让我的应用程序作为PWA工作,我想知道当我部署应用程序的新版本时,如何使现有用户的缓存失效。以下是问题: serviceworker.js需

因此,在我当前的系统中,每当我创建一个javascript包时,我都会在文件名中添加一个哈希值,用于生产构建。我的index.html中没有CDN缓存,因此每当出现新的构建时,就会创建一个指向新的哈希javascript文件名的新index.html。无论何时发生新部署,这都能很好地使捆绑包的缓存失效(代价是我的非常小的index.html没有被缓存)

我想让我的应用程序作为PWA工作,我想知道当我部署应用程序的新版本时,如何使现有用户的缓存失效。以下是问题:

  • serviceworker.js需要有一个固定的文件名(文件名中没有散列),这意味着我的CDN将长期缓存该文件,我不想在每次部署时手动使CDN缓存无效。我想我可以像删除index.html一样删除serviceworker.js上的缓存,因为该文件只下载一次

  • 我的工作人员已在用户浏览器中注册,我不确定是否需要添加一些额外代码来检查是否有新版本的工作人员可用。浏览器如何决定何时尝试更新已注册的serviceworker?我是否可以注销我的服务人员以在PWA中安装新版本?这不会破坏PWA吗

  • My index.html由服务工作者缓存,这意味着使用PWA的用户将永远不会获得我的主JS捆绑包的新版本(因为缓存的index.html将通过文件名中的哈希指向旧捆绑包)。我想我可以删除index.html上的serviceworker缓存,但这样应用程序就不能脱机工作了

  • 如果想脱机使用我的应用程序,我需要我的服务人员能够缓存我的散列JS文件。我想我需要对self.addEventListener('fetch',…)中的文件名做一些处理,以使用缓存版本(如果可用),并在internet可用时定期检查新版本,通过创建一个未缓存的静态JSON文件或具有最新文件名的文件来获取哈希JS包文件名。不过,这似乎是一个不切实际的解决方案


  • 我似乎找不到关于如何处理这些问题的好指南,感觉基于一些选项(比如每X时间重试一次),浏览器应该可以为我做很多工作。是否有一些神奇的HTTP头我不知道?

    我有同样的问题,我今天解决了这个问题。您的
    index.html
    应该由服务人员缓存以进行脱机工作。当用户打开PWA时,所有文件都将从缓存中加载,加载完成后,将从网络中检索service worker,如果有新的service worker,则将下载所有新文件,并安装新的service worker并等待激活。您需要刷新PWA以激活新的服务人员并实际使用更新的应用程序

    我使用了article并创建了我的新服务人员(而不是CreateReact应用程序中的默认服务人员)。本文还解释了检测新的service worker安装,以便您可以通知用户有一个新的更新可用,并刷新PWA


    我希望这能对您有所帮助。

    我想避免使用Workbox,我觉得它太神奇了。我可以看到,它保留了每个缓存文件的“修订版”,就像我在问题4中所想的那样。我希望在serviceworkers中有一种“标准”的方法使缓存失效,但显然没有。这意味着我需要滚动我自己的.oh顺便问一下,你知道window.location.reload(true)是否绕过了service worker缓存吗?我想最简单的解决方案是在未缓存的静态文件中有一个内部版本号,然后对照service worker中的版本号进行检查。每当它发生更改时,只需使整个缓存无效并注销工作进程。一个更智能的解决方案将能够在缓存中保留未更改的文件。我想至少我可以在缓存中保留图像,如果它们的文件名有像IOS中的JS bundlesIn那样的散列,并且当安装PWA时,应用了另一个级别的内存缓存,我使用
    window.location.reload(true)
    来清除它。我不确定服务工作者缓存。@AliSabziNezhad不是
    reload(true)
    弃用的吗?它还能用吗?当我使用它时,我仍然有缓存文件