Refresh scripts imported with importScripts in service worker

importscripts vs import
importscripts is not defined
service worker ttl
service worker update
service worker update cache
web worker import
worker script import
failed to execute 'importscripts' on 'workerglobalscope'

I have a website which has a service worker like:

// Import a script from another domain
importScripts('https://example.com/script.js')

Suppose that script.js is updated with some new code and the service worker is activated due to a push event (the user is the meantime has not visited my website again).

Does importScripts checks for updates each time the service worker is activated or it downloads the script.js just once when the service worker is first installed?

Is there any way to have the service worker code (and in particular the imported scripts) refreshed each time the service worker receives a push message?

From the Service Workers specification, scripts imported via importScripts are stored in a map when the Service Worker is installed/updated and are then reused until a new update. There's a discussion on GitHub with more details.

I can't think of a way to reload the imported scripts when a service worker receives a push message. What is your use case?

Update the service worker and the scripts imported with importScripts, In order to force the update of the imported scripts add a query string to the imported script path. For example, if you have the following line inside your service worker: importScripts('https://pushpad.xyz/service-worker.js'); Change some code inside the mainservice worker (if you only change code inside a script imported with importScriptsthe browser will not detect the change) Visit a page of the website (that activates the service worker or calls serviceWorker.register) – sometimes you also need to refresh that page

It's possible to force the browser to revalidate/check whether code included via importScripts() has been updated by dynamically generating the service worker URL—if this changes every hour, then the browser will download and install a "new" service worker, including all imported scripts.

The following code will cause the browser to check all dependencies every hour:

const MAXAGE = 3600; // seconds until recheck
const URL = `/sw.js?q=${Math.floor(Date.now() / (MAXAGE * 1000))}`;
navigator.serviceWorker.register(URL);

Demo — open JS console and click around; you should see the imported script reloaded every 10 seconds.

(This doesn't completely solve your problem (the service worker is only updated when the user visits the page, not when the push notification is received) but it might be sufficient.)

Service worker: importScripts never updates scripts – Pushpad Blog, update() are completely useless. All the HTTP headers returned (for the imported script or the service worker) are also ignored. This means that� If you had some functionality written in a separate script called foo.js that you wanted to use inside worker.js, you could import it using the following line: importScripts('foo.js'); importScripts() and self.importScripts() are effectively equivalent — both represent importScripts() being called from inside the worker's inner scope.

From chrome 68, this can be done by setting {updateViaCache: 'none'} while registering service worker. It doesn't use cache then for contents of imported files

See full reference about definition at w3 and Chrome Updates

Extend byte-for-byte update check to all service worker importScripts , This implements byte-for-byte update check for service worker scripts imported by importScripts(). Currently, service workers update only when� The easiest solution for the developers would be to have browsers check for updates also in the imported scripts every time they check for updates  for the service worker. One option is to extend byte-to-byte comparison to the whole imported scripts (importScripts) graph. If one node has change, update.

WorkerGlobalScope.importScripts(), The importScripts() method of the WorkerGlobalScope interface synchronously imports one or more scripts into the worker's scope. Update compatibility data on GitHub AbstractWorker � ChromeWorker � DedicatedWorkerGlobalScope � ServiceWorker � SharedWorker � SharedWorkerGlobalScope� @nakedsushi. Did you ever figure out how to handle importScripts() for scripts not located at root? I specifically have an npm package (xlsx.js) which includes a web worker for doing the heavy lifting, but the web worker script is using importScripts() to reference some of the package's dependencies that are included in the npm package, in the same node_modules/xlsx directory.

FR: Update importScripts() urls in a JS ServiceWorker � Issue #108 , However, its service worker imports are not updated. The syntax is: FR: Update importScripts() urls in a JS ServiceWorker #108. Closed. (1) prevents even the cached imported scripts from being executed in the later events. So, let's remove this restriction: #642 (comment) (2) sort of assumed that a specific service worker version and its (cached) imported script resources should map 1:1. So, it currently sets the flag upon a successful install.

importScripts are cached forever � Issue #225 � GoogleChromeLabs , a new version of the service worker, it gets updated but it doesn't reload any changes in files imported via ImportScripts. Maybe there should be a feature to load scripts and inline them into the service-worker.js when swPre. - Remove imported scripts updated flag referenced in importScripts() by using service worker's state item instead. - Have Update's perform the fetch steps cover module scripts. - Confirm dobule-download of imported scripts pointed out in #1023 (comment) never happens; importing a script again always gets the result from the cache. This change basically gets the imported scripts included to the byte-check for updates.

Comments
  • I wrote a blog post with some tips.
  • Yes, unfortunately there's no way to update the imported scripts. The only workaround is to add dummy content to the main service worker code. This is the use case.
  • Yes, but even then you can't force it to be updated when a push message arrives, can you? A less ugly workaround is to use "importedScriptName-" + hash of the contents of the imported script + ".js" as the name of the imported script. This way the content of the service worker will change when the imported script changes.
  • Yes, when a push arrives it checks for updates (I think if the last check for updates was more than 24 hours before). You can't easily generate an hash (the imported script belongs to a different domain...) and people may have static websites (or assets). I've also replied to you on the blog
  • Oh, your clients write the service worker, I thought it was a solution similar to other services (like OneSignal), where you provide the service worker. Btw, I replied on the blog. The dummy content solution requires people to know when the imported scripts have changed (since they need to add the dummy content when the content has changed), doesn't it? The hash solution is instead automatic. The generation is made server-side, so it doesn't matter that they belong to a different domain.
  • Yes, it's like OneSignal: I think they have the exact same problem if they update their scripts. And IMHO it's a problem generating the hash server side because 1. you generate the hash of the included scripts every time 2. otherwise you should also implement a cache system in order to avoid making HTTP requests server side and generating the hash every time
  • A more comprehensive answer to the question of how to deploy updates to service workers: stackoverflow.com/a/43471531
  • This no longer works on Chrome 71+: chromestatus.com/feature/5748516353736704.