Read Setting up ES6 | Leanpub

What are the ES6 modules and CommonJS modules?

This chapter examines how Babel ensures that code it transpiles interoperates properly with normal CommonJS modules. Consult chapter “Modules” in “Exploring ES6” for more information on ES6 modules.

7.1 ES6 modules vs. CommonJS modules

7.1.1 ECMAScript 6 modules

Default export (single export):

// lib.js
export default function () {}

// main.js
import lib from './lib';

Named export (multiple export):

// lib.js
export function foo() {}
export function bar() {}

// main1.js
import * as lib from './lib';
lib.foo();
lib.bar();

// main2.js
import {foo, bar} from './lib';
foo();
bar();

It is possible to combine both styles of export, they don’t conflict with each other.

// lib.js (ES6 module)

// named `export` (multiple export) :
export function foo() {};  // Or,  `export foo = function() {};`
export function bar() {};  // Or,  `export bar function() {};`

// default `export` (single export) :
export default function() {};
// Or,  `export default function single() {}; ` 
// Or,  `export default single = function() {};`

// ---------------------------------------------
// main.js

// default `import` :
import single from './lib';  // Or, `var single = require('./lib').default;`
single();

// named `import` :
import * as lib from './lib';
lib.foo();
lib.bar();

import {foo, bar} from './lib';
foo();
bar();

7.1.2 CommonJS modules

Single exports(module.exports) :

// lib.js
module.exports = function () {};

// main.js
var lib = require('./lib');

Multiple Named exports :

// lib.js
exports.foo = function () {};
exports.bar = function () {};

// ------------------------------
// main1.js
var lib = require('./lib');
lib.foo();
lib.bar();

// -------------------------------
// main2.js
var foo = require('./lib').foo;
var bar = require('./lib').bar;
foo();
bar();

Single exports(module.exports) and multiple named exports are mutually exclusive.
You have to use either one the two styles. Some modules combine both styles as follows:

function defaultExport() {}
defaultExport.foo = function () {};
defaultExport.bar = function () {};

module.exports = defaultExport;

7.1.3 Comparing the two modules formats

ES6 modules have two advantages over CommonJS modules:

First, their rigid structure makes them statically analyzable. That enables, e.g., tree shaking (dead code elimination) which can significantly reduce the size of bundled modules.

Second, imports are never accessed directly, which means that cyclic dependencies are always supported.
In CommonJS, you must code like this, so that the exported entity foo can be filled in later:

var lib = require('./lib');
lib.foo();

In contrast, this style of importing does not work (neither do single exports via module.exports):

var foo = require('./lib').foo;
foo();

More information on cyclic dependencies: Section “Support for cyclic dependencies” in “Exploring ES6”.

Read Setting up ES6 | Leanpub

7.2 How Babel compiles ES6 modules to CommonJS

As an example, consider the following ES6 module.

export function foo() {};
export default 123;

Babel transpiles this to the following CommonJS code:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.foo = foo;
function foo() {};
exports.default = 123;

Leave a Reply