JavaScript modules

Original author: jsmodules.io
  • 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.

Module creation


As an exercise, we will build a simple asapmodule 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. 1

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 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 asapfrom 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 asapand stores it in a variable asapthat 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, animateetc.). There mkdirpis a default export in the Node.js module that creates a directory and a named export called syncthat does the same, but synchronously.

In our case, in addition to the default export, the asapmodule can also provide a function laterthat 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, varor 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 classorlet
// 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 thismodule fs from "fs";

Also popular now: