Since 2015, JavaScript has improved immensely.
It’s much more pleasant to use it now than ever.
In this article, we’ll look at how to use JavaScript modules.
Before ES6
ES5 or earlier don’t have a native module system.
Therefore, there’re various module systems that were created to solve the problem of organizing code.
There’s the CommonHS module system that’s standard ib Node.js.
It has a compact syntax and loads modules synchronously and it’s usable on the server-side.
The Asynchronous Module Definition module system is another popular mobile system.
It has more complex syntax, which lets them work without eval
or a compilation step.
ES6 Modules
ES6 modules create a formal module system that’s standard to JavaScript.
It has a compact syntax and lets us do single exports.
Also, it has support for cyclic dependencies.
There’s direct support for async loading and the loading is configurable.
The syntax is even more compact than the ES6 module syntax.
And it has support for cyclic dependencies.
This is better than CommonJS.
The standard module system has a declarative syntax for imports and exports.
And it has a programmatic loader API to configure how modules are loaded and to conditionally load modules.
Named Exports
With named exports, we can export more than one member of a module.
For instance, we can write:
math.js
export const sqrt = Math.sqrt;
export function add(x, y) {
return x + y;
}
export function subtract(x, y) {
return x - y;
}
to create a module that has several functions exported with the export
keyword.
Then we can import the items by writing:
import { add, subtract } from "./math";
const sum = add(1, 2);
const difference = subtract(1, 2);
We imported the items from the math.js
module.
The named exports are in the curly braces.
Then we can call the functions that we exported below it.
With CommonJS, we use the module.exports
property to export multiple members of a module.
For instance, we can write:
math.js
const sqrt = Math.sqrt;
function add(x, y) {
return x + y;
}
function subtract(x, y) {
return x - y;
}
module.exports = {
sqrt,
add,
subtract
};
index.js
const { add, subtract } = require("./math");
const sum = add(1, 2);
const difference = subtract(1, 2);
We call require
to require the whole module, and then we destructured the entries from the imported module.
Then we can use the imported functions the same way.
Default Exports
Default exports are a type of export that can only happen once in any module.
We can name them anything when we import default exports.
For instance, we can write:
math.js
export default function add(x, y) {
return x + y;
}
to export the add
function as a default export.
And then we can import the function by writing:
index.js
import add from "./math";
const sum = add(1, 2);
To export a class, we can write:
Foo.js
export default class {}
We don’t need a semicolon after the statement.
Then we can import it with:
import Foo from "./Foo";
const foo = new Foo();
We can include or exclude the name for default exports.
So we can write:
`export` `default` `function` baz`() {}`
`export` `default` `class` `Bar` `{}`
or
`export` `default` `function() {}`
`export` `default` `class {}`
Conclusion
Before ES6, there’s no module system that’s standard to the language.
Since then, JavaScript has a native mobile system that we can use to organize our code in a standard way.