The Evolution of Modularization in JavaScript
The Evolution of Modularization in JavaScript
Modularization refers to breaking down a large program into multiple interdependent small files, where each file is a module. The development of modularization in JavaScript has gone through several important stages:
-
Global Function Pattern (No Modularization)
- In the early days, files were included via
<script>tags, and all variables and functions were exposed in the global scope. - Issues: Global naming conflicts, unclear dependencies, difficult maintenance.
// module1.js var name = 'module1'; function foo() { console.log(name); } // module2.js var name = 'module2'; // Naming conflict! function bar() { foo(); } // Unclear dependency - In the early days, files were included via
-
Namespace Pattern
- Encapsulates modules using objects to reduce global variable pollution.
- Issue: Internal data can still be modified directly from the outside, insufficient security.
var myModule = { _count: 0, // Can still be modified externally getCount: function() { return this._count; }, setCount: function(n) { this._count = n; } }; -
IIFE Pattern (Immediately Invoked Function Expression)
- Uses closures to achieve data privatization, exposing only public interfaces.
- Supports dependency injection, forming the basis of modern modularization.
var Module = (function() { var privateVar = 'secret'; function privateMethod() { } return { publicMethod: function() { return privateVar; } }; })(); // Dependency injection version var Module = (function($) { function init() { $('#app').hide(); } return { init: init }; })(jQuery); -
CommonJS Specification
- Primarily used on the server-side (e.g., Node.js), loads modules synchronously.
- Uses
module.exportsto export andrequire()to import.
// math.js function add(a, b) { return a + b; } module.exports = { add }; // main.js const math = require('./math.js'); math.add(2, 3); -
AMD Specification (Asynchronous Module Definition)
- Asynchronous Module Definition, suitable for browser environments.
- Uses
defineto define modules andrequireto load modules.
// Define a module define(['jquery'], function($) { function init() { $('#app').hide(); } return { init: init }; }); // Load a module require(['module'], function(module) { module.init(); }); -
ES6 Modules (Modern Standard)
- Language-level module support, dependencies are determined statically at compile time.
- Uses
exportto export andimportto import.
// math.js export const PI = 3.14; export function circleArea(r) { return PI * r * r; } // main.js import { PI, circleArea } from './math.js'; console.log(circleArea(5));
Key Feature Comparison:
- CommonJS: Dynamic loading, dependencies resolved at runtime, suitable for server-side.
- ES6 Modules: Static loading, dependencies resolved at compile time, supports tree shaking.
- AMD: Asynchronous loading, does not block the page, suitable for browsers.
In modern development, ES6 modules are typically used, combined with bundling tools like Webpack to achieve cross-environment compatibility.