在 Angular 上注册自己的 Service Worker 和它自己的 worker

Sal*_*ter 9 service-worker angular

我有一个需要脱机工作的 Web 应用程序。我想创建我的 service worker 来处理 API 缓存/同步逻辑,并让 angular 的 service worker 缓存应用程序资产。

我让 Angular 工人注册并完美工作。但是我无法注册我的工人。

我尝试了三种方法:

//1. Does not seem to do anything. No worker built, no worker starter.
ServiceWorkerModule.register('./offline.worker', {enabled: environment.production});

//2. The worker does not get built, registering fails since the script does not exist.
navigator.serviceWorker.register('./offline.worker');

//3. The worker gets built, it even gets started, but is not registered as ServiceWorker.
new Worker('./offline.worker', {type: 'module'});
Run Code Online (Sandbox Code Playgroud)

因此,当我们指向 ngsw js 文件时,选项 1 可以很好地使用 angular service worker 上的文档。也许它根本不是为我们的工人工作的?

选项 2 是注册服务人员的记录/标准方式,也许我应该简单地构建我的工作人员?我不知道从哪里开始……我得到的完整错误是

Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope (' http://localhost:8080/ ') with script (' http://localhost:8080/offline.worker '): A bad HTTP response code ( 404) 在获取脚本时收到。

选项 3 按我的预期完成了所有工作。我的工作人员已编译,./offline.worker甚至更改为创建的包!这真的是我期望事情进展的方式。不幸的是,像这样创建的 worker 只是一个 web worker,而不是 ServiceWorker。这意味着它无法处理 FetchEvents...

为了完整起见,这是我的 tsconfig.worker.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/worker",
    "lib": [
      "es2018",
      "webworker"
    ],
    "types": []
  },
  "include": [
    "src/**/*.worker.ts"
  ],
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}
Run Code Online (Sandbox Code Playgroud)

以及用于在生产模式下启动 angular 的命令,因为 Service Worker 不在开发中工作:

ng build --prod
http-server dist/app
Run Code Online (Sandbox Code Playgroud)

Ada*_*ley 6

我们通过使用一个简单的中间脚本加载生成的 ngsw 脚本和我们自己的自定义脚本,在 Angular Service Worker 旁边添加了自定义逻辑。这与 Angular 构建过程配合得很好。

app.module.ts

@NgModule({
  //...
  imports: [
    ServiceWorkerModule.register('sw-master.js', {
      enabled: environment.production
    }),
    //...
  ],
  //...
});
Run Code Online (Sandbox Code Playgroud)

angular.json

...
"assets": [
  ...
  "src/manifest.json",
  "src/sw-custom.js",
  "src/sw-master.js"
],...
Run Code Online (Sandbox Code Playgroud)

sw-master.js

...
"assets": [
  ...
  "src/manifest.json",
  "src/sw-custom.js",
  "src/sw-master.js"
],...
Run Code Online (Sandbox Code Playgroud)

sw-custom.js

只是一个例子......我们正在制作它,以便用户可以点击推送通知并被定向到特定的应用程序视图。

importScripts('./ngsw-worker.js'); // generated by Angular build process
importScripts('./sw-custom.js');
Run Code Online (Sandbox Code Playgroud)