facebook twitter github stack-overflow

JavaScript Modules

December 26, 2015

There are quite a few ways to split your JavaScript files into different chunks or modules. CommonJS (popularized by node), AMD and the new native syntax introduced in ES2015.

Now, this is great and all but how do we run this in the browser? The new ES2015 syntax is not working in any browser and browsers don’t know about require.

Multiple Options

CommonJS can be easily converted to ES5 with Browserify.

Webpack, which categorizes itself as a module bundler, handles both CommonJS and AMD.

“Ok, cool, so we covered CommonJS and AMD but what about ES2015 modules?”

Again, multiple options here!

Use SystemJS. SystemJS loads ES6 modules, AMD, CommonJS and global scripts in the browser and NodeJS. It also comes with its own package manager, jspm.

New kid on the block is, Rich Harris’ Rollup. Rollup is “the next-generation JavaScript module bundler” and does this efficiently. Rollup eliminates unused library code with tree-shaking.

“Tree what?”

Basically Rollup does dead code elimination.

“So why not call it that, then?”

Well, actually instead of excluding dead code, it only includes live code. Confused? Rich Harris himself made an explanatory blog post about this.

Webpack 2 (which is now in beta) will also support the ES2015 syntax. Awesomeness!
Bonus: Webpack 2 also supports tree shaking!

“Allright, so that is the module part tackled, but what about actual ES2015 support?”

The trick is to use a transpiler. 2 popular transpilers are Babel and Traceur.

Webpack 2, for example, will only transpile imports and exports to ES5. If you need to transpile the rest to ES5, you can use, what webpack calls, loaders. Loaders are basically plugins. We’ll use the Babel loader for transpilation.

There is one catch though. Since version 6, Babel was modularized and uses presets to transpile your code. There’s a preset called es2015. You would think you could just use this one and you would be done, but here’s the thing. The preset also includes the transform-es2015-modules-commonjs plugin. Which, you guessed it, transpiles your ES2015 modules to CommonJS. That way Webpack would not be able to tree shake and your final bundle would not be optimal.

The solution is to include all but the transform-es2015-modules-commonjs plugin in your configuration file. Hopefully Babel will launch a new preset without the CommonJS modules plugin. Hint hint

Rollup tackled this issue by creating it’s own preset called babel-preset-es2015-rollup.

Browserify uses the Babelify transformer. As Browserify works with CommonJS you can use Babel’s es2015 preset.

In SystemJS you can also use bower to transpile to ES5.


Lot’s of options! Even if you are using the ES2015 syntax.

Personally I think Webpack 2 is the most promising one of the bunch. At Showpad, the company where I currently work, we also decided to use Webpack 2 for new projects.

But in the end it’s all about personal taste.

Got inspired by our brainstorm session at work, 2ality’s post about tree shaking and Rich Hariss’ post about tree shaking to write this blog post.


comments powered by Disqus