README
1 min read18 headings
14.3 CommonJS & AMD
π Introduction
While ES Modules are the modern standard, understanding CommonJS and AMD is crucial for working with Node.js projects, npm packages, and legacy codebases. This section provides deep coverage of both systems.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β COMMONJS vs AMD COMPARISON β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β
β β COMMONJS β β AMD β β
β β (CJS) β β (Asynchronous Module Def) β β
β βββββββββββββββββββββββββββββββ€ βββββββββββββββββββββββββββββββ€ β
β β β β β β
β β Created: 2009 β β Created: 2010 β β
β β For: Node.js (Server) β β For: Browsers β β
β β Loading: Synchronous β β Loading: Asynchronous β β
β β β β β β
β β require('./module') β β define(['dep'], fn) β β
β β module.exports = {} β β require(['dep'], fn) β β
β β β β β β
β β β Simple syntax β β β Non-blocking β β
β β β Large npm ecosystem β β β Browser optimized β β
β β β Sync = blocks in browser β β β Verbose syntax β β
β β β β β Less common today β β
β βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β
β β
β Both are being replaced by ES Modules, but remain in legacy code β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π― Learning Objectives
By the end of this section, you will:
- β Master CommonJS module patterns
- β Understand the module wrapper function
- β Learn AMD define/require patterns
- β Configure RequireJS for browser modules
- β Convert between module formats
- β Handle interoperability issues
1οΈβ£ CommonJS Deep Dive
How CommonJS Works Internally
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// What Node.js does behind the scenes
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Your code in math.js:
const PI = 3.14159;
function add(a, b) {
return a + b;
}
module.exports = { PI, add };
// Node.js WRAPS it in a function:
(function (exports, require, module, __filename, __dirname) {
// Your code runs inside this wrapper
const PI = 3.14159;
function add(a, b) {
return a + b;
}
module.exports = { PI, add };
// Return module.exports
});
// That's why you have access to:
// - exports (shortcut to module.exports)
// - require (function to load other modules)
// - module (info about current module)
// - __filename (absolute path to this file)
// - __dirname (absolute path to directory)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β COMMONJS MODULE WRAPPER β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Every CommonJS file is wrapped in a function: β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β (function(exports, require, module, __filename, __dirname) β β
β β { β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β YOUR CODE HERE β β β
β β β β β β
β β β const x = 1; β β β
β β β module.exports = { x }; β β β
β β β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β }); β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Parameters Available: β
β βββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ β
β β exports β Shortcut to module.exports β β
β β require β Function to import modules β β
β β module β Reference to current module β β
β β __filename β /home/user/project/src/file.js β β
β β __dirname β /home/user/project/src β β
β βββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CommonJS Export Patterns
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Pattern 1: Exporting an Object
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// math.js
const PI = 3.14159;
const E = 2.71828;
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
// Export as object
module.exports = {
PI,
E,
add,
subtract,
};
// Usage
const math = require('./math');
console.log(math.PI); // 3.14159
console.log(math.add(2, 3)); // 5
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Pattern 2: Exporting a Function
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// logger.js
function createLogger(prefix) {
return {
log: (msg) => console.log(`[${prefix}] ${msg}`),
error: (msg) => console.error(`[${prefix}] ERROR: ${msg}`),
};
}
module.exports = createLogger;
// Usage
const createLogger = require('./logger');
const logger = createLogger('App');
logger.log('Started');
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Pattern 3: Exporting a Class
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// User.js
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
greet() {
return `Hello, I'm ${this.name}`;
}
}
module.exports = User;
// Usage
const User = require('./User');
const user = new User('Alice', 'alice@example.com');
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Pattern 4: Using exports Shortcut
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// utils.js
exports.capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
exports.lowercase = (str) => str.toLowerCase();
exports.VERSION = '1.0.0';
// β οΈ CAUTION: Don't reassign exports!
exports = { something: 'new' }; // β BREAKS the reference!
module.exports = { something: 'new' }; // β
Correct way
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Pattern 5: Augmenting exports and module.exports
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// api.js
// Add individual exports
exports.get = (url) => fetch(url);
exports.post = (url, data) => fetch(url, { method: 'POST', body: data });
// Also set a default function
module.exports = function (baseUrl) {
return {
get: (path) => exports.get(baseUrl + path),
post: (path, data) => exports.post(baseUrl + path, data),
};
};
// Attach the individual methods to the function
module.exports.get = exports.get;
module.exports.post = exports.post;
// Usage (both work):
const createApi = require('./api');
const api = createApi('https://api.example.com');
const { get, post } = require('./api');
The require() Algorithm
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// How require() resolves modules
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 1. Core modules (built-in)
const fs = require('fs'); // Built-in, highest priority
const path = require('path'); // No path = core module
// 2. File modules (relative/absolute paths)
const myModule = require('./myModule'); // Relative
const other = require('../lib/other'); // Parent directory
const abs = require('/home/user/module'); // Absolute
// 3. Node modules (node_modules directory)
const lodash = require('lodash'); // Looks in node_modules
const express = require('express'); // Climbs up directory tree
// 4. Resolution order for require('./myModule'):
// a. ./myModule.js
// b. ./myModule.json
// c. ./myModule.node (native addon)
// d. ./myModule/index.js
// e. ./myModule/index.json
// f. ./myModule/package.json β main field
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β require() RESOLUTION β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β require('X') β
β β β
β βββΆ Is X a core module? (fs, path, http...) β
β β YES β Return core module β
β β β
β βββΆ Does X start with './' or '../' or '/'? β
β β YES β Load as FILE or DIRECTORY β
β β ββββββββββββββββββββββββββββββββββββββ β
β β β TRY IN ORDER: β β
β β β 1. X.js β β
β β β 2. X.json β β
β β β 3. X.node β β
β β β 4. X/index.js β β
β β β 5. X/package.json β main β β
β β ββββββββββββββββββββββββββββββββββββββ β
β β β
β βββΆ Otherwise, search node_modules β
β Start from current directory, climb up β
β ./node_modules/X β
β ../node_modules/X β
β ../../node_modules/X β
β ... until root β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β CACHING: β
β β
β require('X') βββΆ CACHE HIT? βββΆ YES βββΆ Return cached β
β β β
β NO β
β β β
β βΌ β
β Load module β
β Execute code β
β Cache result β
β Return exports β
β β
β // Same module loaded once, result reused β
β require('./a'); // Loads and executes β
β require('./a'); // Returns cached β
β require('./a'); // Returns cached β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Module Caching
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Understanding CommonJS caching
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// counter.js
console.log('Module loaded!');
let count = 0;
module.exports = {
increment: () => ++count,
getCount: () => count,
};
// app.js
const counter1 = require('./counter'); // "Module loaded!" (first time)
const counter2 = require('./counter'); // (nothing - cached!)
const counter3 = require('./counter'); // (nothing - cached!)
console.log(counter1 === counter2); // true (same object!)
console.log(counter2 === counter3); // true
counter1.increment();
console.log(counter2.getCount()); // 1 (shared state!)
// Clearing cache (useful for testing):
delete require.cache[require.resolve('./counter')];
const freshCounter = require('./counter'); // "Module loaded!" (reloaded)
2οΈβ£ AMD Deep Dive
AMD with RequireJS
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// AMD Module Definition
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Simple module (no dependencies)
// math.js
define('math', [], function () {
var PI = 3.14159;
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
// Return public API
return {
PI: PI,
add: add,
subtract: subtract,
};
});
// Module with dependencies
// calculator.js
define('calculator', ['math', 'logger'], function (math, logger) {
// math and logger are injected as arguments
function calculate(a, b, operation) {
logger.log('Calculating...');
switch (operation) {
case '+':
return math.add(a, b);
case '-':
return math.subtract(a, b);
default:
throw new Error('Unknown operation');
}
}
return {
calculate: calculate,
};
});
// Anonymous module (name inferred from filename)
// utils.js
define(['jquery'], function ($) {
function showMessage(msg) {
$('body').append('<div class="message">' + msg + '</div>');
}
return { showMessage: showMessage };
});
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AMD STRUCTURE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β define( β
β 'moduleName', β Optional: Module ID β
β ['dep1', 'dep2'], β Dependencies array β
β function(dep1, dep2) { β Factory function β
β // Module code β
β return { ... }; β Public API β
β } β
β ); β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β LOADING SEQUENCE: β
β β
β define('C', ['A', 'B'], factory) β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β 1. Parse dependency array β β
β β 2. Load A.js (async) β β
β β 3. Load B.js (async, parallel) β β
β β 4. Wait for both to complete β β
β β 5. Execute factory(A, B) β β
β β 6. Cache and return result β β
β βββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Requiring AMD Modules
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Using require() in AMD
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Main entry point - app.js
require(['jquery', 'calculator', 'utils'], function ($, calculator, utils) {
// All dependencies loaded
$(document).ready(function () {
var result = calculator.calculate(5, 3, '+');
utils.showMessage('Result: ' + result);
});
});
// Conditional loading
define(['require'], function (require) {
function loadFeature(name, callback) {
require(['features/' + name], function (feature) {
callback(feature);
});
}
return { loadFeature: loadFeature };
});
// CommonJS-style syntax (supported in AMD)
define(function (require, exports, module) {
var $ = require('jquery');
var math = require('./math');
exports.doSomething = function () {
// Use $ and math
};
});
RequireJS Configuration
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// requirejs.config() - Configure paths, shims, and more
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
requirejs.config({
// Base URL for all module lookups
baseUrl: '/js',
// Path shortcuts
paths: {
jquery: 'lib/jquery-3.6.0.min',
lodash: 'lib/lodash.min',
backbone: 'lib/backbone-min',
text: 'plugins/text', // Text plugin
json: 'plugins/json', // JSON plugin
},
// Shim non-AMD libraries
shim: {
backbone: {
deps: ['lodash', 'jquery'], // Load these first
exports: 'Backbone', // Global variable to export
},
'jquery.plugin': {
deps: ['jquery'],
exports: 'jQuery.fn.plugin',
},
'legacy-lib': {
exports: 'LegacyLib',
init: function () {
// Custom initialization
return this.LegacyLib.noConflict();
},
},
},
// Map module IDs to other IDs
map: {
'some/module': {
jquery: 'jquery-private', // Use private jQuery
},
},
// Require.js plugins config
config: {
text: {
useXhr: function (url, protocol, hostname, port) {
return true; // Always use XHR
},
},
},
// Wait time before timeout (milliseconds)
waitSeconds: 15,
// URL arguments for cache busting
urlArgs: 'bust=' + new Date().getTime(),
});
// Start the app
require(['app/main']);
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β REQUIREJS CONFIG OPTIONS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β baseUrl: '/js' β β
β β β β
β β All module lookups start from this path β β
β β require(['app']) β loads /js/app.js β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β paths: { 'jquery': 'lib/jquery-3.6.0' } β β
β β β β
β β Aliases for module paths (no .js extension!) β β
β β require(['jquery']) β loads /js/lib/jquery-3.6.0.js β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β shim: { 'backbone': { deps: [...], exports: '...' }} β β
β β β β
β β Configure non-AMD scripts: β β
β β β’ deps: modules to load first β β
β β β’ exports: global variable the script creates β β
β β β’ init: custom initialization function β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β urlArgs: 'v=1.0.0' β β
β β β β
β β Append to all URLs for cache busting β β
β β /js/app.js?v=1.0.0 β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3οΈβ£ HTML Integration
Loading AMD Modules
<!-- βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
<!-- AMD with RequireJS in HTML -->
<!-- βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
<!DOCTYPE html>
<html>
<head>
<title>AMD Example</title>
</head>
<body>
<!-- Single script tag loads RequireJS and starts app -->
<script data-main="js/main" src="js/lib/require.js"></script>
<!--
data-main="js/main" tells RequireJS:
1. Set baseUrl to "js/"
2. Load "js/main.js" as entry point
-->
</body>
</html>
<!-- βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
<!-- Alternative: Inline configuration -->
<!-- βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
<!DOCTYPE html>
<html>
<head>
<script src="js/lib/require.js"></script>
<script>
requirejs.config({
baseUrl: 'js',
paths: {
jquery: 'lib/jquery.min',
},
});
require(['app/main'], function (main) {
main.init();
});
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
4οΈβ£ Interoperability
CommonJS in AMD
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Using CommonJS style in AMD
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// AMD supports "Simplified CommonJS Wrapping"
define(function (require, exports, module) {
// CommonJS-style requires
var $ = require('jquery');
var _ = require('lodash');
var myModule = require('./myModule');
// CommonJS-style exports
exports.doSomething = function () {
return _.map([1, 2, 3], (x) => x * 2);
};
// Or use module.exports
module.exports = {
doSomething: function () {
/* ... */
},
};
});
AMD in Node.js
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Using AMD modules in Node.js with amdefine
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Install: npm install amdefine
// myModule.js
if (typeof define !== 'function') {
var define = require('amdefine')(module);
}
define(['./dependency'], function (dep) {
// This works in both AMD (browser) and CommonJS (Node.js)
return {
doSomething: function () {
return dep.helper();
},
};
});
5οΈβ£ Migration Patterns
CommonJS to ES Modules
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Converting CommonJS to ES Modules
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// βββ BEFORE: CommonJS βββ
// math.js
const PI = 3.14159;
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
module.exports = { PI, add, subtract };
// app.js
const math = require('./math');
const { add, PI } = require('./math');
// βββ AFTER: ES Modules βββ
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// app.js
import { PI, add, subtract } from './math.js';
// or
import * as math from './math.js';
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CONVERSION CHEAT SHEET β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β CommonJS ES Modules β
β ββββββββ ββββββββββ β
β β
β module.exports = x; export default x; β
β β
β module.exports = { a, b }; export { a, b }; β
β β
β module.exports.x = y; export const x = y; β
β β
β exports.x = y; export const x = y; β
β β
β const x = require('./m'); import x from './m.js'; β
β β
β const { a } = require('./m'); import { a } from './m.js'; β
β β
β const m = require('./m'); import * as m from './m.js'; β
β β
β require('./m'); import './m.js'; β
β β
β const m = require(path); const m = await import(path); β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β οΈ DIFFERENCES TO WATCH: β
β β
β β’ Add .js extension (required in browsers/Node ESM) β
β β’ No __dirname/__filename (use import.meta.url) β
β β’ No require.resolve (use import.meta.resolve) β
β β’ No dynamic require(var) (use await import(var)) β
β β’ ESM is strict mode by default β
β β’ ESM has top-level await β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Dual Package Support
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// package.json - Supporting both CJS and ESM
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
{
"name": "my-package",
"version": "1.0.0",
// Main entry for CommonJS
"main": "./dist/index.cjs",
// Entry for ES Modules
"module": "./dist/index.mjs",
// Conditional exports (Node.js 12.7+)
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.cjs"
},
"./utils": {
"import": "./dist/utils.mjs",
"require": "./dist/utils.cjs"
}
},
// TypeScript types
"types": "./dist/index.d.ts",
// Files to include in package
"files": ["dist"]
}
6οΈβ£ Summary Comparison
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β COMPLETE COMPARISON β
βββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββ¬ββββββββββββββββββββββββββ€
β Feature β CommonJS β AMD β ES Modules β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Year β 2009 β 2010 β 2015 β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Designed β Node.js β Browsers β Everywhere β
β For β (Server) β β β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Syntax β require() β define() β import/export β
β β module.exports β require() β β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Loading β Synchronous β Asynchronous β Async (browser) β
β β β β Both (Node.js) β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Analysis β Dynamic β Dynamic β Static β
β β (runtime) β (runtime) β (compile-time) β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Tree- β β No β β No β β
Yes β
β Shaking β β β β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Circular β Partial support β Supported β Live bindings β
β Deps β (can be undefined) β β (better handling) β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Current β Legacy Node.js β Rare β β
Standard β
β Usage β Many npm packages β (mostly dead) β Recommended β
βββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββββββββββββββ€
β Tools β Node.js native β RequireJS β Native browsers β
β β Bundlers β β Node.js, bundlers β
βββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββ΄ββββββββββββββββββββββββββ
π Key Takeaways
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β KEY TAKEAWAYS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β COMMONJS: β
β β’ require() / module.exports β
β β’ Synchronous loading (server-side) β
β β’ Still used in Node.js, many npm packages β
β β’ Gradually migrating to ESM β
β β
β AMD: β
β β’ define() / require() β
β β’ Asynchronous loading (browser-side) β
β β’ Mostly deprecated, replaced by ESM β
β β’ May encounter in legacy codebases β
β β
β BEST PRACTICES: β
β β’ New projects: Use ES Modules β
β β’ Libraries: Build both ESM and CJS β
β β’ Use package.json "exports" for dual support β
β β’ Bundlers handle conversion between formats β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Next Steps
Continue to 14.4 Bundlers & Build Tools to learn:
- Webpack configuration
- Rollup for libraries
- Vite for development
- esbuild for speed
- Tree-shaking optimization