facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.71k stars 26.85k forks source link

Service worker support for precaching static files with workbox-cli #11060

Open alzeih opened 3 years ago

alzeih commented 3 years ago

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.

alzeih commented 3 years ago

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?

OliverEvans96 commented 5 months ago

bump :)