Precaching is one of the most common things you'll do in a service worker, and Workbox offers lots of flexibility in how you can accomplish this important task, regardless of which one of Workbox's build tools you choose. In this guide, you'll learn how to precache assets using both generateSW
and injectManifest
, as well as which of these methods might be the best fit for your project.
Precaching with generateSW
generateSW
is the easiest way to precache assets in Workbox. The big thing to remember about generateSW
is that you are not writing your own service worker—you're asking Workbox to generate one for you. However, you can influence its behavior through a variety of configuration options.
generateSW
does different things by default depending on which build tool you use. When using workbox-webpack-plugin
, you don't have to specify any configuration options. By default, the plugin will precache everything webpack includes in its dependency graph and write a service worker named service-worker.js
to the directory specified by output.path
On the other hand, if you use workbox-build
or workbox-cli
, only HTML, CSS and JavaScript assets read from the local filesystem will be precached by default. Configuration-wise, you have to specify swDest
and the globDirectory
option in the generateSW
config for precaching to work. Chances are, you'll want to configure additional options affecting your service worker behavior as well, so take a look through the documentation.
Precaching with injectManifest
Using injectManifest
isn't as easy as using generateSW
, but you're trading off ease of use for greater flexibility. Where generateSW
handles the entire service worker generation for you, injectManifest
takes a service worker you write as its source and injects a list of URLs to precache, while leaving the rest of your service worker as-is.
When you use injectManifest
, you're responsible for wiring up precaching logic. When injectManifest
examines your input service worker, it looks for a special self.__WB_MANIFEST
variable and replaces it with the precache manifest. If this variable isn't present, injectManifest
will throw an error.
The list of entries in the precache manifest can be tweaked with additional configuration options.
Side-by-side comparison
Click on each of the tabs below to compare the usage of the generateSW
and injectManifest
methods:
Since generateSW
generates a service worker, you only need to specify a configuration. Below is an example using workbox-build
:
// build-sw.js
import {generateSW} from 'workbox-build';
generateSW({
swDest: './dist/sw.js',
globDirectory: './dist',
globPatterns: [
'**/*.js',
'**/*.css',
'**/*.svg'
]
});
The service worker can then be built on the command line with Node:
node build-sw.js
Since injectManifest
requires a source service worker, a minimally viable example requires a source service worker file. If all that's needed is precaching, that input service worker might look something like this:
import {precacheAndRoute} from 'workbox-precaching';
precacheAndRoute(self.__WB_MANIFEST);
Note the self.__WB_MANIFEST
string. This is a placeholder that Workbox replaces with the precache manifest. Below is a valid configuration for this use case:
// build-sw.js
import {injectManifest} from 'workbox-build';
injectManifest({
swSrc: './src/sw.js',
swDest: './dist/sw.js',
globDirectory: './dist',
globPatterns: [
'**/*.js',
'**/*.css',
'**/*.svg'
]
});
injectManifest
is preferable if you have complex requirements, such as advanced routing, custom caching strategies, or other things that aren't covered by the options generateSW
provides.
Conclusion
Precaching in Workbox is much simpler than if you had to manage precaching on your own, especially where versioned assets compiled by bundlers are concerned. However, precaching isn't the only thing you'll likely do in a service worker. As you proceed, you'll learn other techniques, such as runtime caching.