Frontend Development 21 min read

Understanding CommonJS and Front-End Module Systems

The article traces JavaScript’s module evolution from inline scripts to CommonJS’s file‑scoped exports and require system, explains its minimal bundler implementation, compares AMD and CMD alternatives, and finally introduces native ES6 import/export syntax, highlighting key differences and the gradual deprecation of CommonJS.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Understanding CommonJS and Front-End Module Systems

The article continues the front‑end knowledge series by explaining the CommonJS specification, which provides a module convention for JavaScript running outside browsers. It starts with a brief definition from Wikipedia and highlights why modularization became essential after Node.js brought JavaScript to the server side.

It then describes the historical evolution of front‑end code: early pages placed all JavaScript directly inside <script> tags, later scripts were moved to separate .js files, and as projects grew the number of files increased dramatically. This caused global‑variable pollution because, before ES6, JavaScript had no built‑in module system or closed scopes.

Developers first tried namespace objects and closures to isolate variables, but these approaches still suffered from fragile dependencies. The need for a robust module system led to the creation of CommonJS.

CommonJS treats each file as an independent module with its own scope. Variables declared inside a file are private unless explicitly exported. Two special variables are provided by the runtime:

require – loads another module and returns its exports object.

module – an object representing the current module; module.exports holds the values that the module makes public.

Example:

// a.js
var name = 'morrain';
var age = 18;
module.exports.name = name;
module.exports.getAge = function () { return age; };

// b.js
var a = require('a.js');
console.log(a.name); // 'morrain'
console.log(a.getAge()); // 18

The article notes that exports is merely a reference to module.exports ; reassigning exports breaks the link and does not export anything.

It also shows a minimal CommonJS implementation used by bundlers such as Browserify or webpack. The implementation keeps a cache of loaded modules and defines a require function that creates a module object, executes the module code, and returns module.exports :

(function (modules) {
  var installedModules = {};
  var require = function (moduleName) {
    if (installedModules[moduleName]) return installedModules[moduleName].exports;
    var module = installedModules[moduleName] = { moduleName: moduleName, exports: {} };
    modules[moduleName].call(module.exports, module, module.exports, require);
    return module.exports;
  };
  return require('index.js');
})({
  'a.js': function (module, exports, require) { /* a.js content */ },
  'b.js': function (module, exports, require) { /* b.js content */ },
  'index.js': function (module, exports, require) { /* entry */ }
});

Beyond CommonJS, the article surveys other front‑end module specifications:

AMD (Asynchronous Module Definition) – implemented by RequireJS. Modules are defined with define and loaded asynchronously, which avoids blocking the browser.

CMD (Common Module Definition) – used by Sea.js. It also uses define but allows a more synchronous‑style coding similar to CommonJS.

Examples for AMD and CMD are provided, showing how to declare modules, list dependencies, and export interfaces.

Finally, the article introduces ES6 modules, the native module system standardized in ECMAScript 2015. It explains the export and import syntax, default exports, and the static nature of ES6 module loading, which enables compile‑time analysis and tree‑shaking. Differences between CommonJS and ES6 modules are highlighted, such as the fact that ES6 imports are hoisted and cannot be dynamic expressions.

Sample ES6 code:

// a.js
export const name = 'morrain';
const age = 18;
export function getAge() { return age; };

// b.js
import { name as aName, getAge } from 'a.js';
export const name = 'lilei';
console.log(aName); // 'morrain'
console.log(getAge()); // 18

The article concludes with a brief recap of module evolution, a note on the deprecation of CommonJS in newer Node.js versions, and a list of reference links.

frontendJavaScriptNode.jsModule SystemCommonJSAMDES6
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.