create-react-app
create-react-app copied to clipboard
Service worker support for precaching static files with workbox-cli
For a Create React App web application with a service worker, I'd like to be able to precache and route static resources like images in a way that is flexible to changes. These are resources that are not known to webpack, but are in the public folder. I want to achieve this without having to eject.
In my case these static resources should be always available to a Progressive Web App, so a runtime caching strategy is not sufficient. They can't be included with webpack as the filenames are from a json file, so are loaded dynamically.
Describe the solution you'd like
Being able to specify additional static resources so they are added to the workbox manifest as a default feature of Create React App, using the inject manifest functionality of workbox.
Describe alternatives you've considered
I tried this with workbox-cli. I installed workbox-cli with npm install workbox-cli
, and created a workbox-config.js
file in the project's root directory with:
module.exports = {
globDirectory: 'public/',
globPatterns: [
'**/*.{png,jpg,jpeg}'
],
swSrc: 'build/service-worker.js',
swDest: 'build/service-worker.js',
injectionPoint: 'self.__CUSTOM_WB_MANIFEST'
};
Note: this file is based off one generated by npx workbox wizard
with some changes.
In my src/service-worker.js
, I added the line (just after the other precacheAndRoute) that matches the workbox-config.js
:
precacheAndRoute(self.__CUSTOM_WB_MANIFEST);
Note: don't use a injection point name that contains self.__WB_MANIFEST
e.g.: self.__WB_MANIFEST_CUSTOM
- this will not work as expected!
I changed the build command in package.json
to:
"build": "react-scripts build && workbox injectManifest",
This lets me select static resources like images matching the globPatterns
from the globDirectory
, and add them to a separate workbox precache manifest that is generated dynamically. This means the revision field for each url is set automatically too, and the list of files is kept up to date when npm run build
is run.
I also considered using this method as a one off and writing to src/service-worker.js
instead of build/service-worker.js
, but I wanted changes to be handled automatically by build scripts.
Additional context
I've seen other solutions using react-app-rewired and craco, but I really wanted a solution that worked with Create React App, so I could continue using a (mostly) supported configuration.
I'm still learning how this works, so there may be a better workaround for this too. I hope that a workaround won't be needed if this is supported by Create React App.
Looking at how this might work, I found:
https://github.com/facebook/create-react-app/blob/382ba21052ffd1321f3e7bb1dcb70d442106dff1/packages/react-scripts/config/webpack.config.js#L729-L741
The documentation for workbox-webpack-plugin.InjectManifest says it supports the config parameter include
:
https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-webpack-plugin.InjectManifest#:~:text=include
I think this could perhaps have a RegExp for adding static files from the public folder to the precache manifest?
bump :)