Caveats

There are a few things you should keep in mind when working with multiple scripts.

Modules Are Not Supported

importScripts only works with scripts, not modules. Using module.exports in the script being imported will throw an error.

Different Files, Same Context of Execution

You can’t use the same variable name at the root level in different scripts which are imported. This will definitely lead to unexpected behaviour and possibly errors. This is because all imported scripts are running in the same context of execution: the worker global scope.

As you might have guessed, reversing the order of params in the call to importScripts() will result in a different output.

importScripts('sw-2.js, sw-1.js');

console.log(currentCacheName); //Output: cache:v1

Updating The Service Worker In The Browser

Making changes in the imported scripts will not trigger an update to the Service Worker. Only changes to the root level worker will be detected by the browser. This means cache-versioning has to be done in the root level worker.

Let me explain using the same example.

Any changes made to sw-1.js or sw-2.js will not trigger an update. The user will still be stuck with the old Service Worker code and the changes will not reflect. To ensure that the latest code is served and a new Worker is registered, we need to make a change in root-service-worker.js .

My preferred way of handling this is using versioning for the Service Worker. Since changing the version has nothing to do with the behaviour of the Service Worker, we need to make sure we don’t introduce any bugs unwittingly. I like to add a comment at the top of root-service-worker.js like so:

/* Bump the service worker version in this comment to make sure changes to imported scripts are reflected on the client/browser. SERVICE WORKER VERSION = 1 */

Any change made to the root worker will cause the browser to recognise that there is an updated worker available. Even a change inside a comment!

NOTE: This is just one way to ensure that the latest updates are served. You can use any other technique that you see fit. The only requirement is that some change is made to the root file.

There seems to be an automated way of doing so as explained here.

Even though passing { updateViaCache: ‘none’ } as the second parameter to navigator.serviceWorker.register is the suggested way to tackle this issue, this did not work for me [ Chrome Version: 75.0.3770.100 (Official Build) (64-bit) ]

There should be a way to handle this automatically, without the need of manual intervention. Once I figure it out, I’ll update the article. Suggestions welcome!