diff --git a/README.md b/README.md index 7a43411..880d8fd 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ The full documentation is in this README, and the - [write(filePath, options, callback)](#writefilepath-options-callback) - [Options Parameter](#options-parameter) - [cacheId [String]](#cacheid-string) + - [clientsClaim [Boolean]](#clientsclaim-boolean) - [directoryIndex [String]](#directoryindex-string) - [dontCacheBustUrlsMatching [Regex]](#dontcachebusturlsmatching-regex) - [dynamicUrlToDependencies [Object⟨String,Array⟨String⟩⟩]](#dynamicurltodependencies-objectstringarraystring) @@ -48,12 +49,14 @@ The full documentation is in this README, and the - [navigateFallbackWhitelist [Array⟨RegExp⟩]](#navigatefallbackwhitelist-arrayregexp) - [replacePrefix [String]](#replaceprefix-string) - [runtimeCaching [Array⟨Object⟩]](#runtimecaching-arrayobject) + - [skipWaiting [Boolean]](#skipwaiting-boolean) - [staticFileGlobs [Array⟨String⟩]](#staticfileglobs-arraystring) - [stripPrefix [String]](#stripprefix-string) - [stripPrefixMulti [Object]](#stripprefixmulti-object) - [templateFilePath [String]](#templatefilepath-string) - [verbose [boolean]](#verbose-boolean) - [Wrappers and Starter Kits](#wrappers-and-starter-kits) + - [Recipes for writing a custom wrapper](#recipes-for-writing-a-custom-wrapper) - [Acknowledgements](#acknowledgements) - [License](#license) @@ -259,6 +262,17 @@ property from your `package.json`. _Default_: `''` +#### clientsClaim [Boolean] +Controls whether or not the generated service worker will call +[`clients.claim()`](https://developer.mozilla.org/en-US/docs/Web/API/Clients/claim) +inside the `activate` handler. + +Calling `clients.claim()` allows a newly registered service worker to take +control of a page immediately, instead of having to wait until the next page +navigation. + +_Default_: `true` + #### directoryIndex [String] Sets a default filename to return for URL's formatted like directory paths (in other words, those ending in `'/'`). `sw-precache` will take that translation @@ -436,6 +450,26 @@ more information about how and why you'd use both libraries together. _Default_: `[]` +#### skipWaiting [Boolean] +Controls whether or not the generated service worker will call +[`skipWaiting()`](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting) +inside the `install` handler. + +By default, when there's an update to a previously installed +service worker, then the new service worker delays activation and stays in a +`waiting` state until all pages controlled by the old service worker are +unloaded. Calling `skipWaiting()` allows a newly registered service worker to +bypass the `waiting` state. + +When `skipWaiting` is `true`, the new service worker's `activate` handler will +be called immediately, and any out of date cache entries from the previous +service worker will be deleted. Please keep this in mind if you rely on older +cached resources to be available throughout the page's lifetime, because, for +example, you [defer the loading of some resources](https://github.com/GoogleChrome/sw-precache/issues/180) +until they're needed at runtime. + +_Default_: `true` + #### staticFileGlobs [Array⟨String⟩] An array of one or more string patterns that will be passed in to [`glob`](https://github.com/isaacs/node-glob). diff --git a/cli.js b/cli.js index 9bbb856..d1dae29 100755 --- a/cli.js +++ b/cli.js @@ -16,6 +16,7 @@ */ /* eslint-env node */ +/* eslint no-nested-ternary: 0 */ 'use strict'; var meow = require('meow'); @@ -35,13 +36,15 @@ function setDefaults(cli, configFileFlags) { compositeFlags.swFile = compositeFlags.swFile || configFileFlags.swFile || 'service-worker.js'; - compositeFlags.swFilePath = compositeFlags.swFilePath || configFileFlags.swFilePath || path.join(compositeFlags.root, - compositeFlags.swFile); + compositeFlags.swFilePath = compositeFlags.swFilePath || + configFileFlags.swFilePath || + path.join(compositeFlags.root, compositeFlags.swFile); compositeFlags.cacheId = compositeFlags.cacheId || configFileFlags.cacheId || cli.pkg.name; - compositeFlags.dynamicUrlToDependencies = compositeFlags.dynamicUrlToDependencies || + compositeFlags.dynamicUrlToDependencies = + compositeFlags.dynamicUrlToDependencies || configFileFlags.dynamicUrlToDependencies; compositeFlags.directoryIndex = compositeFlags.directoryIndex || @@ -88,6 +91,18 @@ function setDefaults(cli, configFileFlags) { compositeFlags.maximumFileSizeToCacheInBytes || configFileFlags.maximumFileSizeToCacheInBytes; + // We can't just use ||, since compositeFlags.skipWaiting might be false. + compositeFlags.skipWaiting = ('skipWaiting' in compositeFlags) ? + compositeFlags.skipWaiting : + (('skipWaiting' in configFileFlags) ? + configFileFlags.skipWaiting : undefined); + + // We can't just use ||, since compositeFlags.clientsClaim might be false. + compositeFlags.clientsClaim = ('clientsClaim' in compositeFlags) ? + compositeFlags.clientsClaim : + (('clientsClaim' in configFileFlags) ? + configFileFlags.clientsClaim : undefined); + return compositeFlags; } diff --git a/lib/sw-precache.js b/lib/sw-precache.js index 85ea34c..9126f17 100644 --- a/lib/sw-precache.js +++ b/lib/sw-precache.js @@ -115,6 +115,7 @@ function generate(params, callback) { return new Promise(function(resolve, reject) { params = defaults(params || {}, { cacheId: '', + clientsClaim: true, directoryIndex: 'index.html', dontCacheBustUrlsMatching: null, dynamicUrlToDependencies: {}, @@ -125,10 +126,11 @@ function generate(params, callback) { maximumFileSizeToCacheInBytes: 2 * 1024 * 1024, // 2MB navigateFallback: '', navigateFallbackWhitelist: [], - stripPrefix: '', - stripPrefixMulti: {}, replacePrefix: '', + skipWaiting: true, staticFileGlobs: [], + stripPrefix: '', + stripPrefixMulti: {}, templateFilePath: path.join( path.dirname(fs.realpathSync(__filename)), '..', 'service-worker.tmpl'), verbose: false @@ -257,6 +259,7 @@ function generate(params, callback) { var populatedTemplate = template(data)({ cacheId: params.cacheId, + clientsClaim: params.clientsClaim, // Ensure that anything false is translated into '', since this will be treated as a string. directoryIndex: params.directoryIndex || '', dontCacheBustUrlsMatching: params.dontCacheBustUrlsMatching || false, @@ -273,6 +276,7 @@ function generate(params, callback) { })), precacheConfig: JSON.stringify(precacheConfig), runtimeCaching: runtimeCaching, + skipWaiting: params.skipWaiting, swToolboxCode: swToolboxCode, version: VERSION }); diff --git a/service-worker.tmpl b/service-worker.tmpl index 2aa7bf0..d49747b 100644 --- a/service-worker.tmpl +++ b/service-worker.tmpl @@ -70,8 +70,10 @@ self.addEventListener('install', function(event) { ); }); }).then(function() { + <% if (skipWaiting) { %> // Force the SW to transition from installing -> active state return self.skipWaiting(); + <% } %> }) ); }); @@ -91,7 +93,9 @@ self.addEventListener('activate', function(event) { ); }); }).then(function() { + <% if (clientsClaim) { %> return self.clients.claim(); + <% } %> }) ); });