A module is a self-contained unit of code, which is usually stored in a file. In ES6, modules get language-level support for component definition. Modules export values, which can then be imported by other modules.
There are two popular standards for JavaScript module loaders.
CommonJS: Used heavily in Node.js
- Syntactically compact
- Loads synchronously
- Used by the server
AMD: Used by RequireJS
- Syntactically complex. Enables AMD to work without compilation.
- Loads asynchronously
- Used by the browser
Import & Export
You have to use the export
keyword to explicitly make it available. And use import
keyword to use the module.
A module loader
provides the ability to dynamically load modules, and also keeps track of all loaded modules in a module registry.
Typically, in production, the module registry would be populated by an initial compiled bundle of modules. Later in the page state, it may become necessary to dynamically load a new module. This module can then share dependencies with the initial page bundle without having to reload any dependencies.
Custom Module Names
Custom module names can be written ./local-module
to load relative to their parent module name. .. syntax is also supported allowing easily portable modules.
ES6 Modules
Exporting
Syntax of ES6 modules was suppose to be a format that both users of CommonJS and of AMD are happy with. But its most similar to the exports.method = function() {}
pattern in NodeJS
of creating multiple named exports.
CommonJS:
exports.someMethod = function() {
...
};
exports.another = {};
In ES6, this will be written as:
export function someMethod() {
...
}
export var another = {};
Notice that the name of the function, class or variable gets used as the export name.
Importing
When importing, we import any exports we need by name, and can also choose to rename them:
import { someMethod, another as newName } from './exporter';
someMethod();
typeof newName == 'object';
Default Import and Export
Sometimes one doesn't want to write an import name at all. For this we can use the default export:
To export:
export default function foo() {
console.log('foo');
}
To import:
import customName from './export-default';
customName(); // -> 'foo'
Supported Import Syntax
There are a few other variations of module syntax, the full list of supported import
statements is listed below:
/* import a module without any import bindings */
import 'jquery';
/* import the default export of a module */
import $ from 'jquery';
/* import a named export of a module */
import { $ } from 'jquery';
/* import a named export to a different name */
import { $ as jQuery } from 'jquery';
/* import an entire module instance object */
import * as crypto from 'crypto';
Supported Export Syntax
A full list of supported export
statements list:
/* export a named variable */
export var x = 42;
/* export a named function */
export function foo() {};
/* export the default export */
export default 42;
/* export the default export as a function */
export default function foo() {};
/* export an existing variable */
export { encrypt };
/* export a variable as a new name */
export { decrypt as dec };
/* export an export from another module */
export { encrypt as en } from 'crypto';
/* export all exports from another module */
export * from 'crypto';
Note that any valid declaration can be exported. In ES6, this includes class (as in the example above), const
, and let
.