The #ChromeDevSummit site is live, happening Nov 12-13 in San Francisco, CA
Check it out for details and request an invite. We'll be diving deep into modern web tech & looking ahead to the platform's future.

Generate a Service Worker with workbox-build

This page explains how to use the workbox-build Node module to generate a complete service worker with precaching and runtime caching.

Install workbox-build

Start by installing `workbox-build` from npm.

npm install workbox-build --save-dev

Call generateSW()

To generate a service worker, you need to add workbox-build.generateSW() to your build process or Node script:

const workboxBuild = require('workbox-build');

// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
  // This will return a Promise
  return workboxBuild.generateSW({
    globDirectory: 'build',
    globPatterns: [
      '**\/*.{html,json,js,css}',
    ],
    swDest: 'build/sw.js',
  });
}

This command will output a service worker to build/sw.js which will precache all the files in the build/ directory that match any of the globPatterns defined.

In your web page, you can register this service worker by adding:

<script>
// Check that service workers are registered
if ('serviceWorker' in navigator) {
  // Use the window load event to keep the page load performant
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js');
  });
}
</script>

Adding Runtime Caching

There may be files that you don't want to precache but will be used by your webapp that you'd like cache at runtime. Images are a great example.

Instead of precaching all images for your site, which will take up a lot of space in the cache, you can cache them as they are used and limit the number of images cached.

Runtime caching can be achieved by adding the runtimeCaching configuration to the options passed into generateSW(). runtimeCaching expects an array of objects that describe the runtime caching rules you want.

In the example below, we'll demonstrate how to cache images and limit that cache to a maximum of 10 images.

const workboxBuild = require('workbox-build');

// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
  // This will return a Promise
  return workboxBuild.generateSW({
    globDirectory: 'build',
    globPatterns: [
      '**\/*.{html,json,js,css}',
    ],
    swDest: 'build/sw.js',

    // Define runtime caching rules.
    runtimeCaching: [{
      // Match any request ends with .png, .jpg, .jpeg or .svg.
      urlPattern: /\.(?:png|jpg|jpeg|svg)$/,

      // Apply a cache-first strategy.
      handler: 'cacheFirst',

      options: {
        // Use a custom cache name.
        cacheName: 'images',

        // Only cache 10 images.
        expiration: {
          maxEntries: 10,
        },
      },
    }],
  });
}

buildSW();

The full set of available options can be found on the workbox-build module page.

Using with Gulp

Using workbox-build with your Gulp process is simply a case of using the same code as above as a Gulp task..

const gulp = require('gulp');
const workboxBuild = require('workbox-build');

gulp.task('service-worker', () => {
  return workboxBuild.generateSW({
    globDirectory: 'build',
    globPatterns: [
      '**\/*.{html,json,js,css}',
    ],
    swDest: 'build/sw.js',
  });
});

After this you can simply run the task via gulp service-worker or add it to the end of another Gulp task.