What's the Workbox CLI?
The Workbox command line interface (contained in the
workbox-cli
package) consists of a Node.js program called workbox that
can be run from a Windows, macOS, of UNIX-compatible command line
environment. Under the hood, workbox-cli wraps the workbox-build module,
and provides an easy way of integrating Workbox into a command line build
process, with flexible configurations.
Install the CLI
Installing the CLI is simple, just run the following command in your terminal.
npm
npm install workbox-cli --global
Yarn
yarn global add workbox-cli
CLI Modes
The CLI has four different modes:
- wizard: A step-by-step guide to set up Workbox for your project.
- generateSW: Generates a complete service worker for you.
- injectManifest: Injects the assets to precache into your project.
- copyLibraries: Copy the Workbox libraries into a directory.
wizard
The Workbox wizard asks a series of questions about your local directory
setup and which files you want precached. Your answers are used to
generate a configuration file which can then be used when running in
generateSW
mode.
Most developers will only need to run workbox wizard once, and you're free to manually customize the initial configuration file that's generated, using any of the supported build configuration options.
To start the wizard run:
workbox wizard
generateSW
You can use the Workbox CLI to generate a complete service worker using a configuration file (like the file generated by the wizard.)
Just run the following command:
workbox generateSW path/to/config.js
Developers who are happy with Workbox's built-in precaching and runtime caching
capabilities, and don't need to customize their service worker's behavior
are recommended to use generateSW
mode.
When to use generateSW
- You want to precache files.
- You have simple runtime configuration needs (e.g. the configuration allows you to define routes and strategies).
When NOT to use generateSW
- You want to use other Service Worker features (i.e. Web Push).
- You want to import additional scripts or add additional logic.
injectManifest
For developers who want more control of their final service worker file
can use the injectManifest
mode. This mode assumes that you have an
existing service worker file (the location of which is specified in config.js).
When workbox injectManifest
is run, it looks for a specific string
(precaching.precacheAndRoute([])
by default) in your source
service worker file. It replaces the empty array with a list of
URLs to precache and writes the service worker file to its
destination location, based on the configuration options in config.js
.
The rest of the code in your source service worker is left untouched.
You can use Workbox in this mode like so:
workbox injectManifest path/to/config.js
When to use injectManifest
- You want more control over your service worker.
- You want to precache files.
- You have more complex needs in terms of routing.
- You would like to use your service worker with other API's (e.g. Web Push).
When NOT to use injectManifest
- You want the easiest path to adding a service worker to your site.
copyLibraries
This mode is helpful if you would like to use injectManifest
and would
like to use the Workbox library files hosted on your own origin instead
of using the CDN.
You just need to run it with a path to write the files to:
workbox copyLibraries third_party/workbox/
Build Process Integration
Why Does Workbox need to Integrate with My Build Process?
The Workbox project contains a number of libraries that work together to power your web app's service worker. In order to use those libraries effectively, Workbox needs to be integrated into your web app's build process. This ensures that your service worker is able to efficiently precache all of your web app's critical content, and keep that content up to date.
Is workbox-cli
the Right Choice for My Build Process?
If you have an existing build process that is based entirely on
npm scripts,
then the workbox-cli
is a good choice.
If you're currently using webpack as your build tool, then using the workbox-webback-plugin is a better choice.
If you're currently using Gulp, Grunt, or some other Node.js-based build tool, then integrating workbox-build into your build script is a better choice.
If you don't have a build process at all, then you should come up with one before using Workbox to precache any of your assets. Trying to remember to run workbox-cli manually can be error-prone, and forgetting to run it can lead to stale content being served to returning visitors.
Setup and Configuration
After installing workbox-cli
as a development
dependency for your local project, you can add the call to workbox
at
the end of your existing build process's npm script:
From package.json:
{
"scripts": {
"build": "my-build-script && workbox <mode> <path/to/config.js>"
}
}
Replace <mode>
with generateSW
or injectManifest
(depending
on your use case) and <path/to/config.js>
with the path to
your configuration options. Your configuration might have been created
automatically by workbox wizard
or tweaked manually.
Configuration
Options used by generateSW
Below is a list of options used by just the generateSW
command.
These options only apply to generateSW . |
|
---|---|
importWorkboxFrom |
Optional
Valid values are
Example: importWorkboxFrom: 'local' |
skipWaiting |
Optional Whether or not the service worker should skip over the waiting lifecycle stage.
When self.addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') { self.skipWaiting(); } });
This allows your web app to trigger Example: skipWaiting: true |
clientsClaim |
Optional Whether or not the service worker should start controlling any existing clients as soon as it activates. Example: clientsClaim: true |
runtimeCaching |
Optional
Passing in an array of objects containing
Requests for precached URLs that are picked up via
The
The Example: runtimeCaching: [{ // Match any same-origin request that contains 'api'. urlPattern: /api/, // Apply a network-first strategy. handler: 'NetworkFirst', options: { // Fall back to the cache after 10 seconds. networkTimeoutSeconds: 10, // Use a custom cache name for this route. cacheName: 'my-api-cache', // Configure custom cache expiration. expiration: { maxEntries: 5, maxAgeSeconds: 60, }, // Configure background sync. backgroundSync: { name: 'my-queue-name', options: { maxRetentionTime: 60 * 60, }, }, // Configure which responses are considered cacheable. cacheableResponse: { statuses: [0, 200], headers: {'x-test': 'true'}, }, // Configure the broadcast update plugin. broadcastUpdate: { channelName: 'my-update-channel', }, // Add in any additional plugin logic you need. plugins: [ {cacheDidUpdate: () => /* custom plugin code */} ], // matchOptions and fetchOptions are used to configure the handler. fetchOptions: { mode: 'no-cors', }, matchOptions: { ignoreSearch: true, }, }, }, { // To match cross-origin requests, use a RegExp that matches // the start of the origin: urlPattern: new RegExp('^https://cors\.example\.com/'), handler: 'StaleWhileRevalidate', options: { cacheableResponse: { statuses: [0, 200] } } }] |
navigateFallback |
Optional
This will be used to create a
This is meant to be used in a Single Page App scenario, in which you want all navigations to use common App Shell HTML. It's not intended for use as a fallback that's displayed when the browser is offline. Example: navigateFallback: '/app-shell' |
navigateFallbackBlacklist |
Optional
An optional array of regular expressions that restricts which URLs the configured
This is useful if only a subset of your site's URLs should be treated as being part of a Single Page App.
If both Example: // Exempt all URLs that start with /_ or contain admin anywhere: navigateFallbackBlacklist: [/^\/_/, /admin/] |
navigateFallbackWhitelist |
Optional
An optional array of regular expressions that restricts which URLs the configured
This is useful if only a subset of your site's URLs should be treated as being part of a Single Page App.
If both Example: // Include URLs that start with /pages: navigateFallbackWhitelist: [/^\/pages/] |
importScripts |
Required
An required list of JavaScript files that should be passed to
If one of the imported files sets the
This is also useful when you want to let Workbox create your top-level service worker file,
but want to include some additional code, such as a Example: importScripts: ['push-notifications.abcd1234.js'] |
ignoreURLParametersMatching |
Optional Any search parameter names that match against one of the regex's in this array will be removed before looking for a precache match. This is useful if your users might request URLs that contain, for example, URL parameters used to track the source of the traffic. Those URL parameters would normally cause the cache lookup to fail, since the URL strings used as cache keys would not be expected to include them. Example: // This will ignore all parameters: ignoreURLParametersMatching: [/./] |
directoryIndex |
Optional
If a navigation request
for a URL ending in This should be configured to whatever your web server is using, if anything, for its directory index. Example: directoryIndex: 'index.html' |
cacheId |
Optional An optional ID to be prepended to cache names used by Workbox.
This is primarily useful for local development where multiple sites may be served from the
same Example: cacheId: 'my-app' |
offlineGoogleAnalytics |
Optional Controls whether or not to include support for offline Google Analytics.
When Example: offlineGoogleAnalytics: true |
cleanupOutdatedCaches |
Optional Whether or not Workbox should attempt to identify an delete any precaches created by older, incompatible versions. Example: cleanupOutdatedCaches: true |
navigationPreload |
Optional Whether or not to enable navigation preload in the generated service worker.
When set to Example: navigationPreload: true, runtimeCaching: [{ urlPattern: ({event}) => event.request.mode === 'navigate', handler: 'NetworkOnly', }] |
Options used by injectManifest
Below is a list of options used by just the injectManifest
command.
These options only apply to injectManifest . |
|
---|---|
swSrc |
Required
The path to the source service worker file that can contain your own customized code, in
addition to containing a match for In Node
Your service worker file should include a call to a
In Webpack Your service worker file should reference the Example: swDest: path.join('src', 'sw.js') |
injectionPointRegexp |
Optional
By default, the
If you want the
Example: // Inject the manifest into a variable assignment: injectionPointRegexp: new RegExp('(const myManifest =)(;)') |
Options used by both
The remaining options are used by both commands.
Used by both generateSW and injectManifest . |
|
---|---|
swDest |
Required The path and filename of the service worker file that will be created by the build process. In node, this will be relative to the current working directory. In webpack, this will be relative to the webpack output directory. Example: swDest: path.join('dist', 'sw.js') |
globDirectory |
Optional
The base directory you wish to match
If you do set this, make sure to also configure Example: // Treat all patterns as relative to the current directory: globDirectory: '.' |
globFollow |
Optional Determines whether or not symlinks are followed when generating the precache manifest.
For more information, see the definition of Example: globFollow: false |
globIgnores |
Optional A set of patterns matching files to always exclude when generating the precache manifest.
For more information, see the definition of Example: globIgnores: ['**/ignored.html'] |
globPatterns |
Optional Files matching against any of these patterns will be included in the precache manifest. For more information, see the glob primer.
Note: Setting Example: globPatterns: ['dist/*.{js,png,html,css}'] |
globStrict |
Optional
If
For more information, see the definition of Example: globStrict: false |
templatedURLs |
Optional If a URL is rendered generated based on some server-side logic, its contents may depend on multiple files or on some other unique string value. If used with an array of strings, they will be interpreted as glob patterns, and the contents of any files matching the patterns will be used to uniquely version the URL. If used with a single string, it will be interpreted as unique versioning information that you've generated out of band for a given URL. Example: templatedURLs: { '/app-shell': [ 'dev/templates/app-shell.hbs', 'dev/**/*.css', ], '/other-page': 'my-version-info', } |
maximumFileSizeToCacheInBytes |
Optional This value can be used to determine the maximum size of files that will be precached. This prevents you from inadvertantly precaching very large files that might have accidentally matched one of your patterns. Example: // Increase the limit to 4mb: maximumFileSizeToCacheInBytes: 4 * 1024 * 1024 |
dontCacheBustURLsMatching |
Optional Assets that match this regex will be assumed to be uniquely versioned via their URL, and exempted from the normal HTTP cache-busting that's done when populating the precache.
While not required, it's recommended that if your existing build process already inserts a
Example: dontCacheBustURLsMatching: /\.\w{8}\./ |
modifyURLPrefix |
Optional A mapping of prefixes that, if present in an entry in the precache manifest, will be replaced with the corresponding value. This can be used to, for example, remove or add a path prefix from a manifest entry if your web hosting setup doesn't match your local filesystem setup.
As an alternative with more flexibility, you can use the Example: modifyURLPrefix: { // Remove a '/dist' prefix from the URLs: '/dist': '' } |
manifestTransforms |
Optional
One or more
If Example: manifestTransforms: [ // Basic transformation to remove a certain URL: (originalManifest) => { const manifest = originalManifest.filter( (entry) => entry.url !== 'ignored.html'); // Optionally, set warning messages. const warnings = []; return {manifest, warnings}; } ] |