Support for ES6 imports in ES5 module

After a few nights of moving code around and installing so many gulp packages I don't even remember all the ones I've tried, I eventually settled on something I'm semi-happy with.

First, to answer my own question, which was also backed up by @Bergi in the comments:

Short answer: No, you cannot, in any way (right now), mix ES6 syntax with ES5 (modules) in a single file because the browser will error out on the use of export.

Long answer: Technically you can set your script-element type to "module", which will make browsers accept the export keyword. However, your code will simply run twice (once on load, and once after importing). If you can live with this, then the no becomes a yes, kinda.

So what did I end up doing? Let me put up front I really wanted to keep the IIFE Module setup I had (for now) in the output ES5 file. I updated my code-base to pure ES6 and tried all kinds of combinations of plugins (including Rollup.js mentioned by @David Bradshaw). But I simply couldn't get them working, or they would completely mangle the output in such a way the browsers couldn't load the module anymore, or drop sourcemap support. With the project the students are doing right now drawing to a close, I already wasted enough of my spare time for the 0.1% of my students. So better luck next year for a "nicer" solution.

  1. I based my UMD pattern (as mentioned by @Sly_cardinal) on jQuery and threw that code into a Library.umd.js. For the ES6 part, I made a Library.es6.js with only a export default Library in it.

  2. In both files, I placed a multiline-comment /*[Library.js]*/ where I wanted to inject the concatenated un-minified Library.js.

  3. I modified my existing Gulp task to just build the Library.js with concat and Babel and stored it on a temporary location. I chose to sacrifice source-map support in this process, as the concatenated code was perfectly readable in the output. Technically source-map support "worked", but it would still throw off the debugger too much.

  4. I added an additional Gulp task to read the contents of the temp Library.js, then for each of the files from Step 1, I would find and replace the multi-line comment with the contents. Save the resulting files, and then throw them through the final concat (eg. bundle with jQuery), terser and sourcemap generation.

The end result is two files:

  • One with UMD/ES5-browser support
  • One with ES6 support

While I'm happy with the result, I don't like the Gulp task chain and the loss of sourcemap support in the first half of the process. As said earlier, I've tried numerous gulp plugins to achieve the same effect (eg. gulp-inject), but they either didn't work properly or did weird things to the sourcemap (even if they claimed to support it).

For a next endeavour I might look into something different than Gulp, or whip up my own plugin which does the above, but properly :P