After executing the create-react-app and enabling the service workers in the index.js
, all relevant files from the src
folder are cached. However some of my resources reside in the public
directory. When I run npm run build
, the asset-manifest.json
and precache-manifest.HASH.js
only contain the HTML, mangled JS and CSS (all stuff from the src
folder).
How can I tell the service worker to additionally cache specific files from the public
folder?
Here is the actually generated precache-manifest.e431838417905ad548a58141f8dc754b.js
self.__precacheManifest = [
{
"revision": "cb0ea38f65ed9eddcc91",
"url": "/grafiti/static/js/runtime~main.cb0ea38f.js"
},
{
"revision": "2c226d1577937984bf58",
"url": "/grafiti/static/js/main.2c226d15.chunk.js"
},
{
"revision": "c88c70e5f4ff8bea6fac",
"url": "/grafiti/static/js/2.c88c70e5.chunk.js"
},
{
"revision": "2c226d1577937984bf58",
"url": "/grafiti/static/css/main.7a6fc926.chunk.css"
},
{
"revision": "980026e33c706b23b041891757cd51be",
"url": "/grafiti/index.html"
}
];
But I want it to also contain entries for these urls:
/grafiti/icon-192.png
/grafiti/icon-512.png
They come from the public
folder.
Alternatively: How can I add my icons for the manifest.webmanifest
file in the src
folder in a way such that I can reference them from the web manifest?
The local cache (e.g., browser) can still cache private responses. You use private when you render your HTML on the server, and the rendered HTML contains user-specific or sensitive information.
Step 1: Create a React application using the following command: Step 2: After creating your project folder i.e. foldername, move to it using the following command: Project Structure: It will look like the following. Now create an assets folder and put any sample image into it, like here we have kept the gfg.png file.
In this example, the browser is going to cache the response for a year according to the max-age directive (60 60 24*365).
You can use it for HTML and service worker script. By analogy, these two are also equivalent. The difference between public and private is that a shared cache (e.g., CDN) can cache public responses but not private responses. The local cache (e.g., browser) can still cache private responses.
I assume that you search for a solution (like me) which works without ejecting. This approach worked for me:
yarn add -D react-app-rewired
Replace react-scripts
in your npm scripts (not needed for eject) inside your package.json
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom",
"eject": "react-scripts eject"
Create a config-overrides.js file in the same level as your package.json
My file looks like this (because I also want to add an own service worker with more sophisticated caching options for my apis) but globPatterns and the globDirectory is what your looking for. After adding this patterns, the matching files (in my case images, music and sounds) were added to the generated precache-manifest-{hash}.
const {InjectManifest} = require('workbox-webpack-plugin');
const path = require('path');
module.exports = {
webpack: function(config, env) {
config.plugins.push(
new InjectManifest({
globPatterns: [
'images/*.png',
'models/*.glb',
'music/*.mp3',
'sound/*.mp3'
],
globDirectory: 'build',
swSrc: path.join('src', 'custom-service-worker.js'),
swDest: 'service-worker.js'
})
);
return config;
}
}
P.S.: if you need a custom-service.worker.js file to get it work, workbox.precaching.precacheAndRoute([])
should be sufficient as content for this file, but the workbox docs are also very interesting for those caching stuff
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With