firebasewebpackbrowser-cacheservice-workersw-precache

How to remove a service worker registered in previous deploy from users' browsers with the newly deployed version of site (Firebase)?


I've deployed a new version of my site (It was on Polymer, now on Vue.js) to Firebase over an existing project.

I'm using default Vue.js template with Webpack (vue init webpack my-project) in the new project


Now that I've deployed the new version, when I open the site I see just a cached shell, I assume that's the service worker's fault

In order to get actual current files from Firebase I (and all the previous visitors) have to now hard refresh the site every time (Ctrl+F5 in firefox)

Console

Now, in browser console (network tab) I see:

enter image description here


I've added this code to firebase.json, then npm run build trying to remove the service worker, but I still have the issue

Firebase.json

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "headers": [
      { "source":"/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}] }
    ]
  }
}

Service worker code from the previous project

I don't use any service workers on the newly deployed version. But the previous deploy registered a service worker

I was using the default sw-precache component from Polymer 1.0 framework's library that was built in the pre-configured Polymer starter kit template that I used. Service worker was generated at build time

Bundled > service-worker.js: https://jsfiddle.net/uydjzw13/

Unbundled > service-worker.js: https://jsfiddle.net/t42fdgow/


Question:

Is there a way to remove that old service worker from all the site visitors' browsers so that they always get the newly deployed version? Maybe I can do that with Webpack or Firebase somehow?


Is it going to get fixed if I just delete the previously deployed version with the service worker from Firebase?

Or maybe I could deploy another version with a service worker that has the only function that deletes all previous cache and unregisters previous service worker, if that's possible?

Or can I use something like this maybe?: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/unregister

I'm not sure how to do that correctly and not accidentally register any more service workers that I also won't be able to get rid of.


Solution

  • I finally found the solution!

    So if you have the same problem, just do this:

    1 Install this webpack plugin (if you're using webpack in your project)

    npm install webpack-remove-serviceworker-plugin

    2 Create the constant in webpack.prod.conf.js file (or whatever your production config is called)

    const RemoveServiceWorkerPlugin = require('webpack-remove-serviceworker-plugin')

    3 Add the plugin into plugins: [ ] in that file (don't put ; there if you don't use them in your project):

    new RemoveServiceWorkerPlugin({ filename: 'service-worker.js' });

    4 change that service-worker.js filename to whatever your service worker was called previously (the one you need to remove. You can find its name in the network tab of developer tools when page is loaded)

    5 Build the project again and deploy


    If you don't use webpack, you can try to do this - replace the old service worker with one that unregisters itself:

    registration.unregister().then(async () => {
      // optionally, get controlled pages to refresh:
      for (const client of await clients.matchAll()) {
        client.navigate(client.url);
      }
    });