
JavaScript modules
- Transfer
- Tutorial
Translation of the “JavaScript Modules” article from jsmodules.io .
The new version of JavaScript will introduce a modular system, mainly inspired by the idea of Node.js modules.
In this article, I will explain how this will work.
As an exercise, we will build a simple
Let's start by creating a new file for our module. Let's call it asap.js. The module provides a single function called default export. You can do the default export using the construct
To import
This construct takes the default function exported by the module
Sometimes modules need to export a few things that can be used by name.
For example, in jQuery, there is one major exports (function
In our case, in addition to the default export, the
Our module looks the same, except that we have added a new export declaration.
Now that we have exported
For the curious, you can import default exports and named exports with a single import statement:
And that’s all there is to it!
Sometimes, when importing a named export, you need to give it your own local name.
It may be convenient to import all named module exports into a single local namespace 2 .
You can make any declaration in JavaScript (for example,
This also works for new ads, such as
These names are also available in the local scope of the module, so you can use them in other functions of the module.
You can export any number of local variables with a single statement.
A group export declaration can be placed anywhere in the file, so you can place the import and export one after the other, at the top of the module.
JavaScript modules have several nice features that simplify their use and refactoring.
1 For real use, this module should be more detailed, but for our example this is enough.
2 Translator's note: it looks like import into the namespace will look like this
The new version of JavaScript will introduce a modular system, mainly inspired by the idea of Node.js modules.
In this article, I will explain how this will work.
Module creation
As an exercise, we will build a simple
asap
module that allows you to assign the execution of actions "as soon as immediately" asynchronously. In Node.js, you can do this with process.nextTick
, there are different approaches that work in many browsers. We will create a module that will work in any environment. 1Let's start by creating a new file for our module. Let's call it asap.js. The module provides a single function called default export. You can do the default export using the construct
export default
.var asap;
var isNode = typeof process !== "undefined" &&
{}.toString.call(process) === "[object process]";
if (isNode) {
asap = process.nextTick;
} else if (typeof setImmediate !== "undefined") {
asap = setImmediate;
} else {
asap = setTimeout;
}
export default asap;
Import module
To import
asap
from another module, we use the following syntax:import asap from "asap";
asap(function() {
console.log("hello async world!");
});
This construct takes the default function exported by the module
asap
and stores it in a variable asap
that we can later call.Named Export
Sometimes modules need to export a few things that can be used by name.
For example, in jQuery, there is one major exports (function
jQuery
) and a few extra named Export ( ajax
, getJSON
, animate
etc.). There mkdirp
is a default export in the Node.js module that creates a directory and a named export called sync
that does the same, but synchronously. In our case, in addition to the default export, the
asap
module can also provide a function later
that assigns code execution to the moment when other network or UI processes have already occurred. Our module looks the same, except that we have added a new export declaration.
var asap;
var isNode = typeof process !== "undefined" &&
{}.toString.call(process) === "[object process]";
if (isNode) {
asap = process.nextTick;
} else if (typeof setImmediate !== "undefined") {
asap = setImmediate;
} else {
asap = setTimeout;
}
export default asap;
export var later = isNode ? process.setImmediate : asap;
Named import
Now that we have exported
later
, we can import it in another module.import { later } from "asap";
later(function() {
console.log("Running after other network events");
});
For the curious, you can import default exports and named exports with a single import statement:
import asap, { later } from "asap";
And that’s all there is to it!
Facilities
Rename named imports
Sometimes, when importing a named export, you need to give it your own local name.
import { unlink as rm } from "fs";
rm(filename, function(err) { /* check errors */ });
Import to namespace
It may be convenient to import all named module exports into a single local namespace 2 .
import * as fs from "fs";
fs.unlink(filename, function(err) { /* check errors */ });
Shortened Export Method
You can make any declaration in JavaScript (for example,
var
or function
) with a named export preceding it with a keyword export
.// exports this function as "requestAnimationFrame"
export function requestAnimationFrame() {
// cross-browser requestAnimationFrame
}
// exports document.location as "location"
export var location = document.location;
This also works for new ads, such as
class
orlet
// exports this class as "File"
export class File() { /* implementation */ }
// exports "0.6.3" as "VERSION"
export let VERSION = "0.6.3";
These names are also available in the local scope of the module, so you can use them in other functions of the module.
Export Grouping
You can export any number of local variables with a single statement.
function getJSON() {
// implementation
}
function postJSON() {
// implementation
}
function animate() {
// implementation
}
A group export declaration can be placed anywhere in the file, so you can place the import and export one after the other, at the top of the module.
Features
JavaScript modules have several nice features that simplify their use and refactoring.
- JavaScript modules support delayed binding between modules for both named exports and default exports. It just works.
- JavaScript modules separate the names existing in the default export (and prototype chains) and the other named export, preventing conflicts.
- With JavaScript modules, it’s easier to determine what exactly you are importing just by looking at the syntax. This improves error messages and also makes it easy to create tools like browserify or JSHint that should work reliably.
Notes
1 For real use, this module should be more detailed, but for our example this is enough.
2 Translator's note: it looks like import into the namespace will look like this
module fs from "fs";