What is CommonJS Module in Javascript ?

CommonJS is a module system used in JavaScript to allow developers to organize their code into smaller, reusable pieces called modules. It was designed to be used on the server side with Node.js, though it can also be used on the client side with tools like Browserify or Webpack. CommonJS modules use the require function to import dependencies and the module.exports or exports object to export modules.

Key Features of CommonJS

  1. Synchronous Loading: CommonJS modules are loaded synchronously. This makes sense for server-side development where file I/O is relatively fast.

  2. Single Export Object: Each module has a single module.exports object that it exports. You can add properties or methods to this object to expose them to other modules.

  3. File-Based Modules: Each file in a CommonJS module system is treated as a separate module.

Basic Example

Creating a Module

Create a file called math.js:

// math.js
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;

module.exports = {
    add,
    subtract
};

In this example, the math.js file exports an object with two methods: add and subtract.

Using a Module

Create another file called app.js:

// app.js
const math = require('./math');

const sum = math.add(5, 3);
const difference = math.subtract(5, 3);

console.log(`Sum: ${sum}`);
console.log(`Difference: ${difference}`);

In this example, app.js imports the math.js module using the require function and then uses the exported add and subtract methods.

Key Functions and Objects

  1. require(): This function is used to import modules. It reads a JavaScript file, executes the file, and returns the exports object.

      const module = require('module-name');
    
  2. module.exports: This object is used to define what a module exports and makes available through require.

      module.exports = {
          foo: function() {},
          bar: 123
      };
    
  3. exports: A shorthand for module.exports. It’s an alias for module.exports that you can use to add properties to the exports object.

      exports.foo = function() {};
      exports.bar = 123;
    

    However, you cannot reassign exports directly if you want to export a different object, as it will break the reference to module.exports.

      // Incorrect
      exports = {
          foo: function() {},
          bar: 123
      };
    
      // Correct
      module.exports = {
          foo: function() {},
          bar: 123
      };
    

Advantages of CommonJS

  • Simplicity: The CommonJS module system is straightforward and easy to use.

  • Wide Adoption: It's the standard module system for Node.js and has been widely adopted in the Node.js ecosystem.

  • Encapsulation: Each file is its own module, which helps in maintaining modularity and separation of concerns.

Limitations of CommonJS

  • Synchronous Loading: CommonJS modules are loaded synchronously, which is not ideal for client-side development due to the potential for blocking behavior.

  • Lack of Native Support in Browsers: CommonJS is not natively supported in browsers. It requires bundling tools like Browserify or Webpack to use in client-side applications.

Comparison with ES Modules (ESM)

With the advent of ES6, JavaScript introduced ES Modules (ESM), which offer a standardized module system with several advantages over CommonJS, such as asynchronous loading, native support in modern browsers, and more sophisticated syntax for importing and exporting modules.

// ES Module example

// math.mjs
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

// app.mjs
import { add, subtract } from './math.mjs';

const sum = add(5, 3);
const difference = subtract(5, 3);

console.log(`Sum: ${sum}`);
console.log(`Difference: ${difference}`);

In summary, CommonJS is a widely used module system in Node.js that allows for modular and maintainable code organization. However, for modern web development, ES Modules are generally preferred due to their asynchronous loading and native browser support.