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.