Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React (CRA) Service Worker Cache "public" folder

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?

like image 264
Constantin Berhard Avatar asked Feb 23 '19 11:02

Constantin Berhard


People also ask

Can the local cache still cache private responses?

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.

How to create a react app from an image?

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.

How long is the browser going to cache the response?

In this example, the browser is going to cache the response for a year according to the max-age directive (60 60 24*365).

What is the difference between public and private cache in SharePoint?

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.


1 Answers

I assume that you search for a solution (like me) which works without ejecting. This approach worked for me:

  1. Install the module react-app-rewired via yarn add -D react-app-rewired
  2. 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"
    
  3. 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

like image 123
Fabian Avatar answered Sep 23 '22 22:09

Fabian