Workbox service worker not updating when Its changed

ramon22 picture ramon22 · Dec 8, 2017 · Viewed 7.1k times · Source

Am using workbox-build-2.1.2 and workbox-sw-2.1.2 with Angular-cli-1.6.0, and everything works fine, but when I update the App and build it for production and the sw.js file is modified then in chrome browser the service worker is not updated it continues to use the old version until I manually un-register it. Should it not install the new sw.js file and when it installs the new version will it also clean the sites old data cashed and start a fresh slate automatically or do I need to set that part?.

Here is how I register sw.js in in Angulars main file:

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .then(registerServiceWorker)
  .catch(err => console.log(err));

function registerServiceWorker() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('sw.js')
      .then(reg => {
        log('Registration successful', reg);
        reg.onupdatefound = () => {
          const installingWorker = reg.installing;
          installingWorker.onstatechange = () => {
            switch (installingWorker.state) {
              case 'installed':
                if (navigator.serviceWorker.controller) {
                  log('New or updated content is available', installingWorker);
                } else {
                  log('Content is now available offline', installingWorker);
                }
                break;
              case 'redundant':
                console.error('The installing service worker became redundant', installingWorker);
                break;
              default:
                log(installingWorker.state);
                break;
            }
          };
        };
      })
      .catch(e => {
        console.error('Error during service worker registration:', e);
      });
  } else {
    console.warn('Service Worker is not supported');
  }
}

my generate-sw file that i run with npm

const workboxBuild = require('workbox-build');
const SRC_DIR = 'src';
const BUILD_DIR = 'public';
const SW = 'sw.js';
const globPatterns = [
  "**/*.{ico,html,css,js,woff,json}"
];

const globIgnores = [
  "sw.js"
];

const input = {
  swSrc: `${SRC_DIR}/${SW}`,
  swDest: `${BUILD_DIR}/${SW}`,
  globDirectory: BUILD_DIR,
  globPatterns: globPatterns,
  globIgnores: globIgnores,
  maximumFileSizeToCacheInBytes: 4000000
};

workboxBuild.injectManifest(input).then(() => {
  console.log(`The service worker ${BUILD_DIR}/${SW} has been injected`);
});

and the base sw.js file

importScripts('workbox-sw.prod.v2.1.2.js');

const workboxSW = new self.WorkboxSW({clientsClaim: true});

workboxSW.precache([]);

workboxSW.router.registerNavigationRoute('/index.html');

*****Update*****

Using express.js for the development server I set the Cache-Control to zero and now when I reload the page the service worker updates to the newer version. Am confused in production with Cache-Control set to days/years how long does it take for a service worker to update then and will it clear the old cash and indexDB or do we have to do it manually

here is the code for express:

app.use('/', express.static(publicFolderPath, {maxAge: 0}));
app.get('*', (req, res) => {
  res.sendFile('index.html');
}); 

Answer

Prashant Mishra picture Prashant Mishra · Mar 28, 2018
  • Service worker won't change while the site is open and it has been updated on the server (that is it won't change in background), it will change when the site is opened after it has been updated. Make sure that the browser isn't caching it, its cache TTL/max-age should be set to 0
  • New service worker won't out of the box clean the old service worker's cache, you will need to do this housekeeping manually on 'Activate' event

Eg:

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName) {
          // Return true if you want to remove this cache,
          // but remember that caches are shared across
          // the whole origin
        }).map(function(cacheName) {
          return caches.delete(cacheName);
        })
      );
    })
  );
});

Refer this link: https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker

Hope this helps