Shipping ES6 ES2015 Modules to Browsers

UPDATE 2017.09.13: Deploying ES2015+ Code in Production Today also provides a good writeup on this subject.

Good workflow fleshed out by Sam Thorogood on using ES2015/ES6 modules with browsers that support, whilst also keeping older browsers (that don’t support it) happy.

The modules

Let’s take these 2 simple modules for example:

// main.js
import {x} from ./foo.js
x().then(y => log(y));
// foo.js
export async function x() {
  let y = await fetch('...');
  y = await y.json();
  return y;
}

Shipping your code to browsers that do support ES6 Modules

  1. Include your main.js script as a module
    <script type="module" src="main.js"></script>
  2. There is no step 2

Shipping your code to browsers that don’t support ES6 Modules (and thus don’t support ES6)

  1. Use tools – like Rollup – to combine all your ES6 modules into one single file
  2. Transpile the generated module from ES6 to ES5
  3. Include the transpiled script as you’d normally do, but with a nomodule attribute so that the browsers that do support ES6 modules don’t load it (*)
    <script nomodule src="compiled.js"></script>

As both methods exclude each other, use ‘m both and you’re good to go 🙂

(*) As also detailed in Jake Archibald’s great introduction to ECMAScript modules (which you should read) there’s one nasty issue though: Safari 10.1 & Mobile Safari 10.3 don’t support the nomodule attribute. Luckily there’s a workaround to fixing this.

Did this help you out? Like what you see?
Consider donating.

I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.