Add information about sending ES6 / ES5 to different browsers
This is documentation about how we solve the following (as mentioned by @zanonnicola and @jon-stevens elsewhere):
If you use async/await for example the code generated by Babel is bloated and slower than native version. What I mean is to ship to modern browser is highly optimised native code.
...you can send your es6 bundle to modern browsers and an es5 bundle to older ones?
Are you thinking about this?
<script type="module" src="main.mjs"></script>
<script nomodule src="main.es5.js"></script>
...you're still using Rollup (or whatever) to bundle everything together, but you create one version of that bundle that isn't transpiled, and another that isn't?
Yeah, after rollup does it's thing I use closure-compiler to transpile it into an es5 bundle.
If that seems like that is a good way forward, we should document it (and how to do it).
Oooh nice thanks David, I think @o-t-w has looked at this, and I think Jon S or Anibe may have found some gotcha.
Incorporating CTM as well it ended up looking like:
<script type="module">
import './javascript/bundle-es6-min.js';
</script>
<script>
(function() {
var linkEl = document.querySelector('link');
if (window.matchMedia && window.matchMedia(linkEl.media).matches) {
var nomodulescript = document.createElement('script');
nomodulescript.src = './javascript/bundle-es5-min.js';
nomodulescript.setAttribute("nomodule", true);
document.body.appendChild(nomodulescript);
}
})();
</script>
There is also the question of whether you want to use any crazy new javascript features that were released after modules, so you might still want to transpile just those new features for the module script... (Babel is pretty configurable as far as what language features you do and don't transpile)
https://github.com/springernature/frontend-components-demo/blob/master/views/layout.hbs https://github.com/springernature/frontend-components-demo/blob/master/package.json
Some older versions of Safari/Firefox don't support 'nomodule' and so load both the module script and the nomodule, so we do a check (catchNoModuleSupport):
if (window.matchMedia && window.matchMedia(linkEl.media).matches) {
var scr = document.createElement('script');
var catchNoModuleSupport = !('noModule' in scr) && 'onbeforeload' in scr;
var scripts = [
{src: local ? '/js/es6-bundle.js' : '/js/es6-bundle.min.js', module: true, 'async': false, 'defer': true},
{src: '/js/es5-bundle.js', module: false, 'async': false, 'defer': true }
];
for (var i in scripts) {
var scriptEl = document.createElement('script');
scriptEl.src = scripts[i].src;
scriptEl.src = scripts[i].src;
if (scripts[i].module === true) {
scriptEl.type = "module";
if (catchNoModuleSupport) {
scriptEl.src = '';
}
} else if (scripts[i].module === false) {
scriptEl.setAttribute('nomodule', true);
}
document.body.appendChild(scriptEl);
}
}