Author: Gilbert Emerson
Reviewers: Chelsey Ong, Ong Shu Peng, Amrut Prabhu
This article assumes the reader has some basic knowledge of JavaScript.
In programming, the term module (other similar terms: package, library, dependency, plugin) is used to refer to a small part of code that is broken up from a larger code base.
Modules help programmers in many ways. Here are some of the examples:
1. Modules make code managable
Using modules to break a code base into smaller parts can make it more manageable, especially for a large code base.
Let's say you have an application with functionalities A and B, where functionality A needs functionality B. Without modules, both of these functionalities are mixed together in the code base without a clear separation. With modules, we can separate these 2 functionalities. When A needs B, A will "include" B and A will be able to work as if A and B had never been separated.
2. Modules help minimize name clashes
Breaking code into modules results in breaking the code's namespace into smaller parts too. This will help in minimizing name clashes and the need for global variables.
3. Modules promote reuse
Modules allow developers to reuse their code. If we have an application that relies on the same string comparison function in multiple files, we can separate that function into a module. Now we can "include" the function from that module instead of repeating that function definition in all the files where it is needed.
There are 3 common ways to use modules in JavaScript: 1. using ES6 modules, 2. using CommonJS, 3. using the module pattern. While ES6 modules is the most recent and the official implementation, this article covers the other two as well because there are still a large number of existing projects that use them.
Introduced in 2015, ES6 modules is the official implementation of modules in JavaScript. It introduces 2 new syntax import
and export
to support modules in JavaScript.
In the example below, index.js
needs the function sumOfVariable
from anExampleModule.js
. So, anExampleModule.js
will need to export the function using the export
syntax and index.js
will need to import that function using the import
syntax.
// anExampleModule.js
var variableOne = 1;
var variableTwo = 2;
export sumOfVariable() {
return variableOne + variableTwo;
}
// index.js
import * as anExampleModule from './anExampleModule.js';
anExampleModule.sumOfVariable(); // 3
ES6 modules supports advanced features such as asynchronous loading, tree shaking, static code analysis and dynamic imports. These features will not be covered in this article.
A more in-depth explanation of ES6 modules can be found in the Modules chapter of the Exploring ES6 online book.
ES6 modules is supported by all major browsers as of 2020. However, you may need to support browsers that do not implement ES6 modules.
One possible solution is to use a transpiler such as Babel and a bundler such as Webpack to serve your application to unsupported browsers.
Alternatively, use the two other methods described below.
CommonJS is in wide use today because it is used by NodeJS which in turn is used by many JavaScript applications.
The example below will replicate the same example in the previous section using CommonJS. index.js
needs the function sumOfVariable
from anExampleModule.js
. So, anExampleModule.js
module will need to export the function using the module.exports
syntax and index.js
module will need to import that function using the require
syntax.
// anExampleModule.js
var variableOne = 1;
var variableTwo = 2;
sumOfVariable = function() {
return variableOne + variableTwo;
}
module.exports = {
sumOfVariable: sumOfVariable,
};
// index.js
var anExampleModule = require('./anExampleModule.js');
anExampleModule.sumOfVariable(); // 3
A more in-depth explanation of CommonJS can be found in the Modules chapter of NodeJS API documentation.
Note that CommonJS modules only work natively in NodeJS. If you would like to use CommonJS modules in browsers, you will still need to use a bundler such as Webpack.
If you are only writing JavaScript for the client side and not using NodeJS at all, and also need to support a wide variety of browsers, consider using the last method described. It has been supported by browsers ever since they started supporting JavaScript.
Using a technique in JavaScript called IIFE (Immediately Invoked Function Expression), JavaScript developers can create a namespace by wrapping their code in an IIFE.
An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.
Syntax: (function() { statements })();
Source: MDN Glossary - IIFE
The example below will replicate the same example in previous sections using the module pattern. index.js
needs the function sumOfVariable
from anExampleNamespace.js
. To achieve this, we use the <script>
tag in HTML to include anExampleNamespace.js
for index.js
to use.
<!-- index.html -->
<script src="./anExampleNamespace.js" />
// anExampleNamespace.js
var anExampleNamespace = (function() {
var variableOne = 1;
var variableTwo = 2;
var sumOfVariable = function() {
return variableOne + variableTwo;
}
// We return an object with functions or variables
// that we want to be exposed
return {
sumOfVariable: sumOfVariable
}
})()
// index.js
anExampleNamespace.sumOfVariable(); // 3
The result of including the script containing the anExampleNamespace
object in the HTML will be as follows:
// anExampleNamespace.js
var anExampleNamespace = (function() {
var variableOne = 1;
var variableTwo = 2;
var sumOfVariable = function() {
return variableOne + variableTwo;
}
// We return an object with functions or variables
// that we want to be exposed
return {
sumOfVariable: sumOfVariable
}
})()
// index.js
anExampleNamespace.sumOfVariable(); // 3
A more in-depth explanation of the module pattern can be found in the this course blog on mastering module pattern.
Although ES6 modules is the official way to implement modules, there are situations where you might have to use one of the other options. Here are some examples:
You can use the module pattern right away by refactoring segments of your code into different files and wrapping your code in an IIFE.
If you are planning to use CommonJS or ES6 modules, you can start by refactoring segments of your code, but you will also need to be familiar with transpilers and bundlers such as Babel and Webpack.
You can read more on JavaScript modules at following websites: