score:1

Accepted answer

since you are using create-react-app for this, there's no need to eject the webpack.config.js (since this is irreversible, i hope you have a git commit you can revert). so here's the general gist:

  • you create a file called chatloader.js outside of your react project (if you don't intend to learn how to configure this in the same webpack config, which might get a little tricky) and add babel transpilation and minification by yourself.
  • this file contains something like (untested)
/**
 * loads a javascript file asynchronously
 * @param {string} url must be valid in <script async src=
 * @returns {promise<htmlscriptelement>}
 */
function loadscriptasync(url) {
  return new promise((resolve, reject) => {
    const script = document.createelement("script");
    script.onload = () => resolve(script);
    script.onerror = () => reject(new error(`could not load script ${url}`));
    script.async = true;
    script.src = url;
    document.getelementsbytagname("head")[0].appendchild(script);
  });
}

function loadstyleasync(src) {
  return new promise((resolve, reject) => {
    const link = document.createelement("link");
    link.href = src;
    link.rel = "stylesheet";
    link.onload = () => resolve(link);
    link.onerror = () => reject(new error(`style load error for ${src}`));

    document.head.append(link);
  });
}

async function fetchmanifest() {
  // todo: add error handling for production code!
  const res = await fetch("https://your-url/path/asset-manifest.json");
  const text = await res.text();
  return json.parse(text)["entrypoints"]; // we only want to load the entrypoints from this file
}

(async() => {
  // this is the main function
  const entries = await fetchmanifest();
  for(const entry of entries){
    // this is loading all entries at once, not waiting for the first entry to be loaded before taking the next one
    if(entry.endswith(".css")){
       loadstyleasync(`https://your-url/path/${entry}`)
    } else if (entry.endswith(".js")) {
       loadscriptasync(`https://your-url/path/${entry}`)
    }    
  }
})();

you can (when you get the chatloader.js to work) just embed this one file into your client's code and it should preload the latest build of your react app.


Related Query

More Query from same tag