javascriptreactjswebpackwebpack-5dynamic-import

Dynamically import react if it's not defined


This question doesn't have anything to do with React.l_a_z_y. Every other search result revolves around React.l_a_z_y, so let's try to refrain from using that keyword on this page!

The goal is quite simple. I want to create a reusable react component, that can be used via cdn, and not include react in the bundle by default. React should be dynamically imported if it's not defined the global window or globalThis object.


Solution

  • Very simple approach: avoid any fancy new esm stuff. Just hand-write es5.

    You might want to avoid caching this file. Consider it like a manifest.json or index.html.

    // init.js
    (function(){
      var tags = [];
    
      if (!React) {
        // React CDN links: https://legacy.reactjs.org/docs/cdn-links.html
        tags.push('<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>');
        tags.push('<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>');
      }
      tags.push('OUR_REACT_APP_CDN_LINK')
    
      var tagsTag = document.createDocumentFragment();
      tagsTag.innerHTML = tags.join('');
      document.body.appendChild(tagsTag);
    })();
    

    Some build process would need to search/replace OUR_REACT_APP_CDN_LINK.

    Not part of question, but, you may want to make sure your app works with React v18 double renders. This should ensure it works with react 17 and 16.8. If consumers are using a react version less than 16.8, they should update so that hooks are available. There are codemods to update to react 16, and there are no breaking changes from react v16->16.8. Actually, it'd be good for consumers to just update all the way to latest react v17, and if they have build issues, use latest react 16.x.