Angular v10 Service Worker 官方更新方法不起作用

Angular v10 Service Worker Official Update Methodology Doesn't Work

编辑摘要:我创建了一个最小的 reproducible example

我不再认为这与 css 或与此相关的任何 @font-face 声明有关。问题在于 swUpdate.checkForUpdate() 的官方 Angular 方式可能与 appRef.isStable 订阅结合使用。

我认为现在正在发生的事情是 angular 提供的 swUpdate 服务误认为存在实际更新,即使缓存内容的散列值保持不变。

我通过将 angular.json 文件中的所有 css 文件更改为如下所示来解决这个问题:

{
   "input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
   "bundleName": "material-theme",
   "inject": false
}

然后我做了一个简单的服务,将捆绑的样式表添加到我的 header。我可以在任何时间点添加它们,甚至可以选择在应用程序加载几分钟后添加它们(下面的 swUpdate 事件多次触发)。

    const appIsStable$ = this.appRef.isStable.pipe(takeWhile(isStable => isStable === true));
    const everyMinute$ = interval(60*1000);
    const swUpdateCheck$ = concat(appIsStable$, everyMinute$);

    swUpdateCheck$.subscribe(() => {
      console.log('update check');
      this.swUpdate.checkForUpdate().then(() => {
        console.log('new version available');
        if(this.window.confirm('New version available. Click OK to download')){
          this.swUpdate.activateUpdate().then(() => {
            this.window.location.reload();
          });
        }
      }, (rej) => {
        debugger;
      });
    });

它仍然提示我更新应用程序。

关于这个我读到了两件事 -

  1. Devtools 实际上可能会破坏 service worker 运行s cache-busting.
  2. 的自然循环
  3. Angular 建议您通过 checkForUpdates() 订阅他们的可观察事件并使用 app.isStable 事件多次触发的方式。

我创建了一个最小的 reproducible example 并且确实确认主要更新问题在于 Angular 官方文档中的更新方法检查。

简单地 npm install 然后 运行 一个 http-server 像这样的来自 dist 文件夹的实例

http-server -p 4200 -c-1 ./sw-css-test

你会明白我的意思的!

原版Post:

问题 - 在没有物理更改任何文件的情况下,服务人员认为有更新需要出去获取。

情况:使用 Angular 10 配置软件可用。导入多个库如Angular Material等

理论:Angular material 尝试获取 Google 字体 'Roboto'(如果在本地文件树中找不到),如下所述我捆绑的 style.css 文件中的片段。因为它使用 url() 函数作为回退,所以它会在缓存中查找并找到它,如 service worker 的 304 响应所示,未修改。但是,由于 style.css 文件发生了变化(大概是因为它找到了字体?),它返回了 200 响应。然后这会提示 service worker 的缓存破坏,它认为有更新需要出去获取。

一旦你获得更新,冲洗、清洗、重复,你就有了一个无限的更新循环。当您的应用程序有实际更新时他们应该去下载,这对于尝试提示用户是不利的。为什么会这样?

以下内容是从 css.

捆绑包中截取的
@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 400;
    src: local("Roboto"),local("Roboto-Regular"),url(roboto-v20-latin-ext_latin-regular.5cb5c8f08bb4e6cb64c3.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-regular.ae804dc012b1b5255474.woff) format("woff")
}

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 500;
    src: local("Roboto Medium"),local("Roboto-Medium"),url(roboto-v20-latin-ext_latin-500.0b45721325446d537b54.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-500.e492ac63197a57e7f4d3.woff) format("woff")
}

@font-face {
    font-family: Roboto;
    font-style: normal;
    font-weight: 700;
    src: local("Roboto Bold"),local("Roboto-Bold"),url(roboto-v20-latin-ext_latin-700.1d1ef7788f0ff084b881.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-700.8aba6dc5d991e4367d7a.woff) format("woff")
}

“网络”选项卡中的代码段

我的思路是否正确?

建议的解决方案:找出一种方法让 material 库引用 Roboto 的静态版本。

还有其他更好的解决方案吗?

参考我的ngsw-config.json:

{
  "$schema": "../node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/manifest.webmanifest",
          "/*.css",
          "/*.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ]
}

注意:我已尝试从服务工作者中删除所有 css 文件和 ttf、woff 和 woff2 资产。然而它仍然带着更新回来。

非常感谢任何帮助。谢谢。

您是否尝试过查看 v10 specific documentation 并检查以确保它按照您上面的描述正常工作?

看起来无论有没有更新,承诺总是会解决。尝试将 available observable 与 checkForUpdate()?

结合使用

另外,尝试从 ngsw-config.json 中提取您的清单文件,看看是否也有帮助。我以前在该文件中看到过哈希不匹配。

在你的 config.url 之后 ngsw/state 的输出是什么?