0
votes

In order to handle cache in PWA, I am changing the name of the file ngsw-worker.js to ngsw-worker22.js (adding incremental number each time a new build is created) in main.ts

After the build I rename the generated ngsw-worker.js to ngsw-worker22.js as well.

When I run my app on browser, I get this error -

main-es2015.642820dbdb6b7b3ca0e0.js:1 Service worker registration failed with: DOMException: Failed to register a ServiceWorker for scope ('https://example.com/apptest/') with script ('https://example.com/apptest/ngsw-worker.js'): The script has an unsupported MIME type ('text/html').

Why is it still looking for ngsw-worker.js , when I see in console, it shows me registered?

Please note - My web app uses Cordova so the cached pages are of Cordova, as you can see in network, service workers are also working

enter image description here

enter image description here

2
you should usually change something INSIDE the service worker like your cache nameIfaruki

2 Answers

1
votes

You should not bind the SW name with a version and keep renaming it, since it can cause issues on the client.

What it can happen is that the browser will register the new SW (ngsw-worker22.js), but the old service worker remains installed too.

It is considered an anti-pattern (aka, bad practice) renaming a SW. You can simply change any of the files within the SW scope in order to alter its hashtable and tell the SW that new data is available on the server so the SW can cache it.

If you want to ship some metadata (like release notes) with each version, you can use the appData property in the ngsw.json file.

From Angular.io:

This section enables you to pass any data you want that describes this particular version of the app. The SwUpdate service includes that data in the update notifications. Many apps use this section to provide additional information for the display of UI popups, notifying users of the available update.

Like:

{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "appData": {
    "version": "1.0.0",
    "changelog": "Updated Angular to v.10.0.2"
  },
  "assetGroups": [
    {
     ...
    }
   ]
}

After a PROD build, your dist folder will have a ngsw.json file. Inside the target assets are registered in a hashtable like the example below. This hash values are used by the SW to determine if there is a new version of the asset on the Server as this ngsw.json file is downloaded at each page (re)load.

"hashTable": {        
    "/assets/icons/icon-152x152.png": "7479a9477815dfd9668d60f8b3b2fba709b91310",
    "/assets/icons/icon-512x512.png": "559d9c4318b45a1f2b10596bbb4c960fe521dbcc",
    "/assets/icons/icon-72x72.png": "c457e56089a36952cd67156f9996bc4ce54a5ed9",
    "/assets/icons/icon-96x96.png": "3914125a4b445bf111c5627875fc190f560daa41",
    "/favicon.ico": "84161b857f5c547e3699ddfbffc6d8d737542e01",
    "/index.html": "a975fbc21acc838a26b5a9f4a32f51cabefd66e6",
    "/main.3ad4b6e924d02c367683.js": "b4e507433cb30a760dfdc8b7591f25af2ddd0f1a",
    "/manifest.webmanifest": "88d5a912c54f29fe0743a02be3c6f208cc7d5880",
    "/styles.59cf8d767805b2930ef2.css": "93d8472f3f9e95fe245335903d6a64333fdbd353"
  },

BONUS INFO:
If you deploy a new version without a ngsw.json, as soon as the SW will detect that this file is missing (throwing a 404 Error) the SW Cache and the SW itself will be deleted. This is a sort of safety measure to remove potential malformed caches/SW versions and ensure that these are erased from the clients accessing the web app.

0
votes

I haven't used Cordova so perhaps there is some difference, but when I use Service Worker with Angular, the reference is in angular.json. This could be why your change is not taking effect.

"ngswConfigPath": "ngsw-config.json"

Having said that, I wonder why you are changing the service worker file name at all? The browser automatically detects a new version when the app is opened or refreshed. You don't have to do anything.