SE-EDU
  • AB-1
  • AB-2
  • AB-3
  • AB-4
  • Collate
  • Book
  • Home
  • Contribute
  • About
  • GitHub
  • Learning Resources for Software Engineering Students »

    Javascript: Modules

    Author: Gilbert Emerson
    Reviewers: Chelsey Ong, Ong Shu Peng, Amrut Prabhu

    This article assumes the reader has some basic knowledge of JavaScript.

    What Is a Module?

    In programming, the term module (other similar terms: package, library, dependency, plugin, etc.) 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 the code more managable
    Using modules will break the code base into smaller parts which if done well can help in managing a code base, especially a large one.

    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 those 2 functionalities into separate module each. When A need B, A will "include" B and A will be able to work as if A and B has never been separated.

    2. Modules help minimize name clashes
    Breaking code into modules result 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 allows developers to reuse their code that is contained in a module. If for example we have an application that rely on a fuctionality such as string comparison function, we can separate that function into a module and let the application to use the function from that module instead of having to always repeating that function in all the places where it is needed.

    How to Modularize JavaScript Code?

    There are 3 common ways to use modules in JavaScript: 1. using ES6 modules, 2. using CommonJS, 3. using the module pattern. While ES6 is the most recent and the official implementation, this article covers the other two as well because there is still a large number of existing projects that use them.

    ES6 modules

    Introduced in 2015, ES6 modules is the official implementation of modules in JavaScript. It introduces 2 new syntax import and export to use modules in JavaScript.

    In the example below, index.js needs the function sumOfVariable from anExampleModule.js. So, anExampleModule.js module will need to export the function using export syntax and index.js module will need to import that function using 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, etc. These features will not be covered in this article.

    Due to the very recent adoption of ES6 modules by browsers and there is still some browsers that do not support it, you might not be able to use ES6 modules right away in those unsupported browsers.

    There are 2 workarounds for this issue. You can use transpiler such as Babel and bundler such as Webpack to serve your application to those unsupported browsers or use one of the other two approaches mentioned below.

    A more in-depth explanation of ES6 modules can be found in the Modules chapter of the Exploring ES6 online book.

    CommonJS

    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 previous chapter using CommonJS. index.js needs the function sumOfVariable from anExampleModule.js. So, anExampleModule.js module will need to export the function using module.exports syntax and index.js module will need to import that function using 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
    

    If your project does not use NodeJS and does not allow the use of bundler such as Webpack, you can consider the approach given in the next section as it does not need any external tool.

    A more in-depth explanation of CommonJS can be found in the Modules chapter of NodeJS API documentation.

    Module Pattern

    Using a technique in JavaScript called IIFE (Immediately Invoked Function Expression), JavaScript developers can create module 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 chapters using module pattern. index.js needs the function sumOfVariable from anExampleModule.js. To achieve this, we use the <script> tag in HTML to import anExampleModule.js for index.js to use.

    <!-- index.html -->
    
    <script src="./anExampleModule.js" />
    <script src="./index.js" />
    
    // anExampleModule.js
    
    var anExampleModule = (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
    
    anExampleModule.sumOfVariable(); // 3
    

    The result of importing the modules in the HTML will be as follow:

    // anExampleModule.js
    
    var anExampleModule = (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
    
    anExampleModule.sumOfVariable(); // 3
    

    A more in-depth explanation of module pattern can be found in the this course blog on mastering module pattern.

    Which to use?

    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:

    • If your application does not allow you to use transpiler and bundler (e.g. because of the additional overhead they add), you can use the module pattern.
    • If your application is NodeJS based, you might want to use CommonJS because NodeJS does not natively support ES6 modules.

    How to start?

    You can start with module pattern right away by refactoring segments of your code into different files and wrapping the code in 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 transpiler and bundler such as Babel and Webpack.

    Further Reading

    You can read more on JavaScript modules at following websites: