Wednesday 15 January 2020

Register own Service Worker on Angular alongside its own worker

I have an web application that needs to work offline. I want to create my service worker to handle the API caching/sync logic, and let the angular's service worker cache the application assets.

I got the Angular worker to register and work perfectly. But I could not get to register my worker.

I tried three methods:

//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'});

So, option 1 works fine using the docs on the angular service worker when we point to the ngsw js file. Maybe it is simply not made to work for our workers?

Option 2 is the documented/standard way to register service workers, maybe I should simply get my worker to be built? I do not know where to start to do that... The complete error I get is

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) was received when fetching the script.

Option 3 gets everything done as I would have expected. My worker is compiled the ./offline.worker is even changed to the bundle created! That's really how I would have expected to get things going. Unfortunately the worker created like so is only a web worker, not a ServiceWorker. This means it does not get to handle FetchEvents...

For sake of completeness, here is my tsconfig.worker.json

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

And the commands used to launch angular in production mode since service workers do not worker in develop:

ng build --prod
http-server dist/app


from Register own Service Worker on Angular alongside its own worker

No comments:

Post a Comment