Search code examples
reactjswebpackprogressive-web-appsworkbox

How to add additional files to CRA WorkBox Precache?


So, I want to make a PWA for one of my CRA projects. The app has a different wallpaper everytime it loads, which it gets through an API. But since PWAs are supposed to have offline support, I wanted to have a fallback wallpaper which is cached. Or, even better the last result from the API is cached and returned till the user is offline. Something of a StaleWhileRevalidate strategy. But I can't figure out how to achieve this without ejecting from create-react-app. Any ideas?

Thanks


Solution

  • Ok, I figured it out myself. In case anyone else needs this, you can create a file named add_to_precache.js in your project's root directory and add the following code to it:

    let fs = require('fs');
    let build_dir = "./build";
    let precache_re = /precache-manifest\.[a-zA-Z0-9]*\.js/
    
    let urls_to_add = [
       /*
     Path to files you want to add relative to build directory. Along with any other homepage value you have. Eg: "/app/background.jpg"
    */
    ]
    
    function generate_revision(){
        var chars = "abcdefghijklmnopqrstuvwxyzABCDEEFGHIJKLMNOPQRSTUVWXYZ0123456789".split('');
        var revision = '';
        for(let i=0;i<24;i++){
            revision += chars[Math.round(Math.random() * 62)];
        }
        return revision;
    }
    
    
    fs.readdir(build_dir, (err, files) => {
        for(let file of files){
            if(precache_re.test(file)){
                let cont = fs.readFileSync(build_dir + '/' + file).toString()
                cont = cont.slice(0, cont.length - 4)
    
                urls_to_add.forEach((url) => {
                    cont += `,\n  {\n    "url": "${url}",\n    "revision": "${generate_revision()}"\n  }`
                })
    
                cont += `\n]);`
                fs.writeFileSync(build_dir + '/' + file, cont);
                break;
            }
        }
    })
    

    And then modify your package.json from

    //....
    "scripts": {
       //....
       "build": "react-scripts build"
       //...
    }
    //...
    }
    

    to

    //....
    "scripts": {
       //....
       "build": "react-scripts build && node add_to_precache"
       //...
    }
    //...
    }
    

    And you are done. It will do the trick when building the application