A node module to generate service worker code that will precaches specific resource so they work offline.

Serving your local static resources cache-first means that you can get all the crucial scaffolding for your web app – your app shell – on the screen without having to wait for any network responses.

Installation

1
yarn add --dev sw-precache

Overview

  1. Make sure your site is served using HTTPS.

  2. incorporate sw-precache into your node-based build script.

  3. Register the service worker JavaScript.

Considerations

  • Service worker caching should be considered a prograssive enhancement. If you follow the model of conditionally registering a service worker only if it’s supported(determined by if('serviceWorker' in navigator)), you’ll get offline support on browsers with service workers and on browsers that don’t support service workers, the offline-specific code will never be called.

  • All resources that are precached will be fetched by a service worker runing in a separate thread as soon as the service worker is installed. You should be judicious in what you list in the dynamicUrlsToDependencies and staticFileGlobs options, since listing files that are non-essential(large-images that are not shown on every page, for instance) will result in browsers downloading more data than is strictly necessary.

  • Precaching doesn’t make sense for all types of resource. Other caching strategies can be used in conjunction with sw-precache to provide the best experience for your users. If you do implement additional caching logic, put the code in a separate file and include it using the importScripts() method.

  • sw-precache uses a cache-first strategy, which results in a copy of any cached content being returned without consulting the network.

Use with webpack

1
yarn add --dev sw-precache-webpack-plugin

Basic Usage

A simple configuration example that will work well in most production environments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const path = require('path')
const SWPrecachePlugin = require('sw-precache-webpack-plugin')

const PUBLIC_PATH = 'https://www.my-project-name.com/'

module.exporst = {
entry: {
main: path.resolve(__dirname, 'src/index')
},
output: {
path: path.resolve(__dirname, 'src/bundles/'),
filename: '[name]-[hash].js',
publicPath: PUBLIC_PATH,
},
plugins: [
new SWPrecachePlugin({
cacheId: 'my-project-name',
dontCacheBustUrlsMatching: /\.\w{8}\./,
filename: 'service-worker.js',
minify: true,
navigateFallback: PUBLIC_PATH + 'index.html',
staticFileGlobsIgnorePatterns: [
/\.map$/,
/asset-manifest\.json$/,
]
})
]
}

This will generate a new service worker at src/bundles/service-worker.js, then you would register it in your application:

1
2
3
4
5
(function() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./service-worker.js')
}
})()

Configuration

  • filename: string - service worker filename, default is service-worker.js

  • filepath: string - service worker path and name, default is to use webpack.output.path + options.filename. This will override filename.

  • staticFileGlobsIngorePatters: [Regexp] - Define an optional array of regex patterns to filter out of staticFileGlobs.

  • mergeStaticsConfig: [boolean] - Merge provided staticFileGlobs and stripPrefixMulti with webpack’s config, rather than having those take precedence, default is false.

  • minify: [boolean] - Set to true to minify and uglify the generated service-worker, default is false.

  • cacheId: [string] - Not required but you should include this, it will give your service worker cache a unique name, default to sw-precache-webpack-plugin.

  • importScripts: [Array<String|Object>]

    • when importScripts array item is a string, converts to object format: { filename: '<publicPath>/my-scripts.js'}

    • when importScripts array item is an Object

      • look for chunkName property

      • look for filename property

  • replacePrefix: [String] - should only be used in conjunction with stripPrefix

  • staticFileGlobs: [Array] - Omit this to allow the plugin to cache all your bundles’ emitted assets. If mergeStaticsConfig=true: this value will be merged with your bundles’ emitted assets, otherwise this value is just passed to sw-precache and emitted assets won’t be included.

  • stripPrefix: [String] - Same as stripPrefixMulti[stripPrefix] = ‘’

  • stripPrefixMulti: [Object<String,String>] - Omit this to use your webpack config’s output.path + /: output.publicPath.

Note taht all configuration options are optional. SWPrecacheWebpackPlugin will by default use all your assets emitted by webpack’s compiler for the staticFileGlobs parameter and your webpack config’s {[output.path + '/']: output.publicPath} as the stripPrefixMulti parameter. This behavior is probably what you want, all your webpack assets will be cached by your generated service worker. Just don’t pass any arguments when you initialize this plugin, and let this plugin handle generating your sw-precache configuration.

1
2
3
plugins: [
new SWPrecacheWebpackPlugin(),
]