0

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.

Devin Rhode
  • 23,026
  • 8
  • 58
  • 72
  • Why would you want to do this? I can't think of a single advantage of doing this. It'll probably just make your page less responsive. – Liam Mar 22 '23 at 14:56
  • Does this answer your question? [async loading javascript with document.write](https://stackoverflow.com/questions/13003644/async-loading-javascript-with-document-write) – Liam Mar 22 '23 at 15:02
  • @Liam - if react is already loaded, we don't want to load it again, let alone load a version which is not the same. For a slow enough connection, this would make page load faster, because we're sending fewer bytes to the browser. – Devin Rhode Mar 22 '23 at 15:04
  • But that can also mean you end up with incompatible versions of React? This is what npm is for. If your component is packaged with the correct dependancies then npm would de-dupe react for you – Liam Mar 22 '23 at 15:06
  • FYI that other question is really focused on document.write, which is rather legacy imo. – Devin Rhode Mar 22 '23 at 15:07
  • We do support other internal teams loading our react "widget" via a private cdn link. Some don't use react, some do. – Devin Rhode Mar 22 '23 at 15:08
  • @Liam regarding "incompatible" versions of react: The pedantic thing would be to test our form with multiple different versions of react, and we may need to do that. However, I'm pretty confident if we ensure compatibility with react 18, we'll be fine. React has very few breaking changes. React 18 will be a very slow upgrade across super huge companies, so supporting both seems reasonable to me. – Devin Rhode Mar 22 '23 at 15:27
  • Loading two different versions of react on the page can cause all sorts of issues, this is one example I was facing: https://legacy.reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react – Devin Rhode Mar 22 '23 at 16:00
  • @Liam Does this make sense? I don't think this question should be closed, I couldn't find anything like this anywhere else. – Devin Rhode Mar 22 '23 at 16:01

1 Answers1

1

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.

Devin Rhode
  • 23,026
  • 8
  • 58
  • 72