Modules in JavaScript

Modules in JavaScript

This article explains modules in JavaScript.

YouTube Video

Modules in JavaScript

Modules in JavaScript are a way to organize code and split it into reusable components. By using modules, code readability and maintainability are improved, and the same functionality can be reused in other projects. Here we explain various module systems, from the concept of modules to specific usage examples.

The Concept of JavaScript Modules

JavaScript did not originally have a modular system. However, as applications grew larger, modularization became important to divide code into smaller units for reuse. A module is a chunk of code with a specific function that can be managed independently of other code, allowing it to be divided into multiple files.

Main Types of Modules

There are several module systems in JavaScript. The most common ones are ES Modules (ESM) and CommonJS.

  • ES Modules is a module system introduced in ECMAScript 2015 (ES6), which defines modules using the import and export keywords. This system is widely used both on the client side (browsers) and the server side (Node.js).

  • CommonJS is a module system primarily used in Node.js. Modules are defined using require and module.exports to import and export files.

Details of ES Modules (ESM)

ES Modules is the standard module system in JavaScript, allowing easy exchange of functionalities between modules. In browsers and Node.js, this system is used to define and import modules.

export and import

export is a keyword for exposing functionalities from a module to the outside. import is used to incorporate functionalities defined in other modules.

Example: Module Export

Modules can be exported in ES Modules as follows.

1// math.mjs
2export function add(a, b) {
3    return a + b;
4}
5export function subtract(a, b) {
6    return a - b;
7}

In this math.mjs module, the functions add and subtract are exported. These functions can be imported from other modules.

Here, .mjs is a file extension that explicitly indicates an ES Modules format JavaScript file. In Node.js, the file extension determines whether it is CommonJS or ES Modules. However, if type: "module" is specified in package.json, files with the .js extension are treated as ES Modules by default.

Example: Module Import

Modules can be imported in ES Modules as follows.

1// main.mjs
2import { add, subtract } from './math.mjs';
3
4console.log(add(3, 5)); // 8
5console.log(subtract(10, 7)); // 3

In this way, using import, you can easily utilize functions defined in other files.

Default Export and Named Export

There are two export methods for modules. One is named export, and the other is default export.

  • Named exports are used when exporting multiple functions or variables from a module. You can perform multiple exports, and upon import, you receive them with specified names.
1// utils.mjs
2export function sum(a, b) {
3    return a + b;
4}
5export function multiply(a, b) {
6    return a * b;
7}
1// main.mjs
2import { sum, multiply } from './utils.mjs';
3
4console.log(sum(4, 6));       // 10
5console.log(multiply(3, 5));  // 15
  • Default export is used when exporting a single function or class from a module. During import, it can be received with any name.
1// greet.mjs
2export default function greet() {
3    return "Hello, World!";
4}
1// main.mjs
2import greet from './greet.mjs';
3
4console.log(greet()); // "Hello, World!"

Only one default export is possible, but named exports can export multiple elements simultaneously.

Example of use on the client side (browser).

Example: Module Export

Modules can be exported in ES Modules as follows.

1// utils.js
2export function sum(a, b) {
3    return a + b;
4}
5export function multiply(a, b) {
6    return a * b;
7}

In this utils.js module, the functions sum and multiply are exported.

Example: Module Import

Modules can be imported on the client side as follows.

 1<!DOCTYPE html>
 2<html lang="ja">
 3<head>
 4  <meta charset="UTF-8">
 5  <title>ES Modules Sample in HTML</title>
 6</head>
 7<body>
 8  <h1>ES Modules Sample</h1>
 9  <div id="result"></div>
10
11  <script type="module">
12    import { sum, multiply } from './utils.js';
13
14    const result = `
15      <p>sum(3, 5) = ${sum(3, 5)}</p>
16      <p>multiply(10, 7) = ${multiply(10, 7)}</p>
17    `;
18
19    document.getElementById('result').innerHTML = result;
20    console.log(sum(3, 5));      // 8
21    console.log(multiply(10, 7)); // 70
22  </script>
23</body>
24</html>
  • By setting the type attribute of the <script> tag to module, ES module syntax such as import and export can be used within HTML.
  • The import statement loads the external utils.js and displays the result.

Details of CommonJS

CommonJS is a module system mainly used in Node.js. Modules are exported and imported using module.exports and require.

require and module.exports

In CommonJS, module.exports is used to export modules. Also, require is used to utilize modules from other files.

Example: Module Export

Modules can be exported in CommonJS as follows.

1// math.js
2module.exports = {
3    add: function(a, b) {
4        return a + b;
5    },
6    subtract: function(a, b) {
7        return a - b;
8    }
9};
Example: Module Import

Modules can be imported in CommonJS as follows.

1// main.js
2const math = require('./math.js');
3
4console.log(math.add(4, 7));      // 11
5console.log(math.subtract(9, 2)); // 7

In Node.js, CommonJS is used as the default module system, but ES Modules are also supported.

Dynamic Import

In JavaScript, modules can be dynamically imported using import(). This method utilizes asynchronous processing to load modules when needed.

Dynamic imports can be done as follows.

1async function loadModule() {
2    const math = await import('./math.js');
3    console.log(math.add(5, 3)); // 8
4}
5
6loadModule();

Dynamic import is one way to enhance application performance. Since you can load modules as needed instead of loading all at the initial load, it improves page display speed.

Advantages of Modules

  • Code Reusability

    • Modularized code can be reused in other projects. By creating modules with common functionality and using them across multiple applications, development efficiency is significantly improved.
  • Improved Maintainability

    • By splitting code into modules, it's easier to modify specific features or parts. Managing code in small units makes it easier to find and fix bugs.
  • Avoiding Namespace Collisions

    • Defining many variables and functions in the global scope can lead to name collisions, but modularization prevents this and helps maintain a cleaner codebase.
  • Dependency Management

    • Using modules allows you to explicitly manage the dependencies of an application. It becomes clear which module depends on other modules, making the code structure easier to understand.

Summary

JavaScript's module system is a powerful means to organize code and split it into reusable components. By understanding the differences between ES Modules and CommonJS and choosing the appropriate module system based on the project, you can enhance code readability and maintainability. Moreover, by utilizing dynamic imports, you can optimize application performance.

Let's leverage the module system to build more scalable and efficient JavaScript applications.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video