javascript
examples
examples.jsā”javascript
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// ā COMMONJS & AMD MODULES ā
// ā Legacy Module Systems for Node.js & Browsers ā
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā MODULE SYSTEMS COMPARISON ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā āāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā CommonJS ā AMD ā ES Modules ā ā
ā āāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāā⤠ā
ā ā Environment ā Node.js ā Browser ā Universal ā ā
ā ā Loading ā Synchronous ā Asynchronous ā Async (static) ā ā
ā ā Syntax ā require/ ā define/require ā import/export ā ā
ā ā ā module.exports ā ā ā ā
ā ā When Created ā 2009 ā 2010 ā 2015 (ES6) ā ā
ā ā Dynamic ā Yes ā Yes ā Via import() ā ā
ā ā Tree-shaking ā No ā No ā Yes ā ā
ā āāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā CommonJS: Server-side (Node.js) - synchronous loading ā
ā AMD: Browser-side - asynchronous loading with RequireJS ā
ā ES Modules: Modern standard - both environments ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// PART 1: COMMONJS MODULES
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā COMMONJS OVERVIEW ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā CommonJS = The original Node.js module system ā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā math.js main.js ā ā
ā ā āāāāāāāā āāāāāāā ā ā
ā ā ā ā
ā ā // Export // Import ā ā
ā ā module.exports = { const math = require('./math'); ā ā
ā ā add: (a,b) => a + b math.add(2, 3); // 5 ā ā
ā ā }; ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Key Characteristics: ā
ā ⢠Synchronous loading (blocking) ā
ā ⢠module.exports = value to export ā
ā ⢠require(path) to import ā
ā ⢠Modules cached after first load ā
ā ⢠Still widely used in Node.js ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// 1.1 BASIC COMMONJS EXPORTS
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā COMMONJS EXPORT PATTERNS ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Pattern 1: module.exports = object ā
ā Pattern 2: module.exports = function ā
ā Pattern 3: exports.name = value (shorthand) ā
ā Pattern 4: module.exports = class ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// Simulating CommonJS module system
const CommonJSSimulator = (function() {
const moduleCache = new Map();
return {
// Simulated require function
require(moduleFactory) {
// In real CommonJS, this would:
// 1. Resolve the path
// 2. Check cache
// 3. Load and execute module
// 4. Return exports
const module = { exports: {} };
const exports = module.exports;
// Execute module factory
moduleFactory(module, exports);
return module.exports;
}
};
})();
// āāā Pattern 1: Exporting an Object āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// File: math.js
const mathModule = CommonJSSimulator.require((module, exports) => {
// Using module.exports for the entire object
module.exports = {
PI: 3.14159,
E: 2.71828,
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
},
multiply(a, b) {
return a * b;
},
divide(a, b) {
if (b === 0) throw new Error('Division by zero');
return a / b;
},
power(base, exp) {
return Math.pow(base, exp);
}
};
});
console.log('CommonJS Pattern 1 - Export Object:');
console.log(' math.add(5, 3):', mathModule.add(5, 3));
console.log(' math.PI:', mathModule.PI);
console.log('');
// āāā Pattern 2: Exporting a Function āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// File: greet.js
const greetModule = CommonJSSimulator.require((module, exports) => {
// Export a single function
module.exports = function greet(name) {
return `Hello, ${name}!`;
};
// Add properties to the function
module.exports.formal = function(name) {
return `Good day, ${name}.`;
};
module.exports.casual = function(name) {
return `Hey ${name}!`;
};
});
console.log('CommonJS Pattern 2 - Export Function:');
console.log(' greet("World"):', greetModule('World'));
console.log(' greet.formal("Sir"):', greetModule.formal('Sir'));
console.log('');
// āāā Pattern 3: Using exports Shorthand āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// File: utils.js
const utilsModule = CommonJSSimulator.require((module, exports) => {
// exports is a reference to module.exports
// Can add properties directly
exports.capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
exports.reverse = function(str) {
return str.split('').reverse().join('');
};
exports.truncate = function(str, length) {
if (str.length <= length) return str;
return str.slice(0, length) + '...';
};
// WARNING: Don't reassign exports directly!
// exports = { something } // This BREAKS the reference!
});
console.log('CommonJS Pattern 3 - exports Shorthand:');
console.log(' utils.capitalize("hello"):', utilsModule.capitalize('hello'));
console.log(' utils.reverse("hello"):', utilsModule.reverse('hello'));
console.log('');
// āāā Pattern 4: Exporting a Class āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// File: Logger.js
const LoggerModule = CommonJSSimulator.require((module, exports) => {
class Logger {
constructor(prefix = '') {
this.prefix = prefix;
}
log(message) {
console.log(`${this.prefix ? `[${this.prefix}] ` : ''}${message}`);
}
error(message) {
console.error(`${this.prefix ? `[${this.prefix}] ` : ''}ERROR: ${message}`);
}
warn(message) {
console.warn(`${this.prefix ? `[${this.prefix}] ` : ''}WARN: ${message}`);
}
}
// Export the class itself
module.exports = Logger;
});
console.log('CommonJS Pattern 4 - Export Class:');
const logger = new LoggerModule('App');
logger.log('Application started');
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// 1.2 COMMONJS REQUIRE PATTERNS
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā COMMONJS REQUIRE PATTERNS ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā // Basic require ā
ā const module = require('./module'); ā
ā ā
ā // Destructuring require ā
ā const { add, subtract } = require('./math'); ā
ā ā
ā // Core modules ā
ā const fs = require('fs'); ā
ā const path = require('path'); ā
ā ā
ā // npm packages ā
ā const express = require('express'); ā
ā ā
ā // Conditional require ā
ā if (condition) { ā
ā const optional = require('./optional'); ā
ā } ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// Simulated require patterns demonstration
console.log('CommonJS Require Patterns:');
// Pattern: Destructuring from required module
const mathOps = CommonJSSimulator.require((module) => {
module.exports = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b
};
});
// In real CommonJS:
// const { add, subtract } = require('./math');
const { add, subtract } = mathOps;
console.log(' Destructured add(10, 5):', add(10, 5));
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// 1.3 MODULE.EXPORTS VS EXPORTS
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā module.exports vs exports ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā // Initially: ā ā
ā ā exports = module.exports = {} ā ā
ā ā ā ā
ā ā // Both reference the same object ā ā
ā ā āāāāāāāāāāāāāāā ā ā
ā ā ā exports āāāāā¼āāāāāāāā ā ā
ā ā āāāāāāāāāāāāāāā ā āāāāāāāāāāāāāā ā ā
ā ā āāāāāāāŗā {} ā ā ā
ā ā āāāāāāāāāāāāāāāāāāā ā āāāāāāāāāāāāāā ā ā
ā ā ā module.exports āā¼āāāā ā ā
ā ā āāāāāāāāāāāāāāāāāāā ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā RULE: What you require() is ALWAYS module.exports ā
ā ā
ā ā exports.foo = 'bar' // Works (adds to same object) ā
ā ā module.exports.foo = 'bar' // Works ā
ā ā module.exports = { foo } // Works (replaces the object) ā
ā ā exports = { foo } // BREAKS! (detaches from module.exports) ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
console.log('module.exports vs exports:');
// CORRECT: Adding to exports
const correctModule1 = CommonJSSimulator.require((module, exports) => {
exports.a = 1;
exports.b = 2;
// Both work because exports still references module.exports
});
console.log(' Correct (exports.x = y):', correctModule1);
// CORRECT: Replacing module.exports
const correctModule2 = CommonJSSimulator.require((module, exports) => {
module.exports = { x: 10, y: 20 };
});
console.log(' Correct (module.exports = {}):', correctModule2);
// INCORRECT: Reassigning exports (BROKEN!)
const brokenModule = CommonJSSimulator.require((module, exports) => {
exports = { broken: true }; // This breaks the reference!
// exports no longer points to module.exports
});
console.log(' Broken (exports = {}):', brokenModule, 'ā Empty because exports was detached');
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// 1.4 COMMONJS MODULE CACHING
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā MODULE CACHING (SINGLETON) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Modules are cached after first load! ā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā // counter.js ā ā
ā ā let count = 0; ā ā
ā ā module.exports = { ā ā
ā ā increment() { count++; }, ā ā
ā ā getCount() { return count; } ā ā
ā ā }; ā ā
ā ā ā ā
ā ā // file1.js ā ā
ā ā const counter = require('./counter'); ā ā
ā ā counter.increment(); // count = 1 ā ā
ā ā ā ā
ā ā // file2.js ā ā
ā ā const counter = require('./counter'); // Same instance! ā ā
ā ā console.log(counter.getCount()); // 1 (not 0!) ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā The cache can be accessed via: require.cache ā
ā Clear cache: delete require.cache[require.resolve('./module')] ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// Simulating module caching
const ModuleSystem = (function() {
const cache = new Map();
return {
require(name, factory) {
// Check cache first
if (cache.has(name)) {
console.log(` [Cache Hit] ${name}`);
return cache.get(name);
}
console.log(` [Loading] ${name}`);
const module = { exports: {} };
factory(module);
// Cache the exports
cache.set(name, module.exports);
return module.exports;
},
clearCache(name) {
cache.delete(name);
}
};
})();
console.log('Module Caching Demonstration:');
// Factory for counter module
const counterFactory = (module) => {
let count = 0;
module.exports = {
increment() { count++; },
decrement() { count--; },
getCount() { return count; }
};
};
// First require - loads the module
const counter1 = ModuleSystem.require('counter', counterFactory);
counter1.increment();
counter1.increment();
console.log(' After 2 increments:', counter1.getCount());
// Second require - returns cached instance
const counter2 = ModuleSystem.require('counter', counterFactory);
console.log(' New require, same count:', counter2.getCount(), '(same instance!)');
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// PART 2: AMD (ASYNCHRONOUS MODULE DEFINITION)
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā AMD OVERVIEW ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā AMD = Designed for browsers with asynchronous loading ā
ā Implemented by: RequireJS, curl.js, Dojo ā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā // Define a module ā ā
ā ā define('moduleName', ['dep1', 'dep2'], function(dep1, dep2) { ā ā
ā ā return { ā ā
ā ā // module contents ā ā
ā ā }; ā ā
ā ā }); ā ā
ā ā ā ā
ā ā // Require modules ā ā
ā ā require(['module1', 'module2'], function(mod1, mod2) { ā ā
ā ā // Use modules ā ā
ā ā }); ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Key Characteristics: ā
ā ⢠Asynchronous loading (non-blocking) ā
ā ⢠Designed for browsers ā
ā ⢠Dependencies declared upfront ā
ā ⢠Callback receives resolved dependencies ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// 2.1 AMD MODULE DEFINITION
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā AMD DEFINE PATTERNS ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Pattern 1: Named module with dependencies ā
ā define('name', ['dep1', 'dep2'], function(dep1, dep2) { ... }) ā
ā ā
ā Pattern 2: Anonymous module with dependencies ā
ā define(['dep1'], function(dep1) { ... }) ā
ā ā
ā Pattern 3: Simple module (no dependencies) ā
ā define(function() { ... }) ā
ā ā
ā Pattern 4: Object literal (no dependencies, static) ā
ā define({ key: 'value' }) ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// Simulating AMD module system
const AMD = (function() {
const modules = new Map();
const pending = new Map();
function define(name, deps, factory) {
// Handle different call signatures
if (typeof name !== 'string') {
factory = deps;
deps = name;
name = 'anonymous_' + Math.random().toString(36).slice(2);
}
if (!Array.isArray(deps)) {
factory = deps;
deps = [];
}
// If factory is an object, wrap it
if (typeof factory !== 'function') {
const obj = factory;
factory = () => obj;
}
// Store module definition
modules.set(name, { deps, factory, resolved: null });
console.log(` [AMD] Defined module: ${name}`);
return name;
}
function require(deps, callback) {
if (typeof deps === 'string') {
deps = [deps];
}
// Resolve all dependencies
const resolved = deps.map(dep => {
const module = modules.get(dep);
if (!module) {
throw new Error(`Module not found: ${dep}`);
}
if (!module.resolved) {
// Resolve the module's dependencies first
const depsResolved = module.deps.map(d => {
const m = modules.get(d);
return m ? m.resolved || m.factory() : undefined;
});
module.resolved = module.factory(...depsResolved);
}
return module.resolved;
});
// Call the callback with resolved modules
if (callback) {
callback(...resolved);
}
return resolved[0];
}
return { define, require };
})();
console.log('AMD Module Definition:');
// Pattern 1: Named module with dependencies
AMD.define('constants', [], function() {
return {
PI: 3.14159,
E: 2.71828
};
});
// Pattern 2: Module depending on another module
AMD.define('geometry', ['constants'], function(constants) {
return {
circleArea(radius) {
return constants.PI * radius * radius;
},
circleCircumference(radius) {
return 2 * constants.PI * radius;
}
};
});
// Pattern 3: Simple module (no dependencies)
AMD.define('utils', function() {
return {
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
};
});
// Pattern 4: Object literal
AMD.define('config', {
apiUrl: 'https://api.example.com',
timeout: 5000
});
// Using require to load and use modules
AMD.require(['geometry', 'constants'], function(geometry, constants) {
console.log(' Circle area (r=5):', geometry.circleArea(5).toFixed(2));
console.log(' PI constant:', constants.PI);
});
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// 2.2 AMD SPECIAL DEPENDENCIES
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā AMD SPECIAL DEPENDENCIES ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Special AMD dependencies: ā
ā ā
ā ⢠require: Local require function for dynamic loading ā
ā ⢠exports: Object to attach exports to ā
ā ⢠module: The module object (like CommonJS) ā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā define(['require', 'exports', 'module'], function(require, exports, module) {ā
ā ā // CommonJS-style inside AMD ā ā
ā ā const dep = require('./dep'); ā ā
ā ā exports.value = 42; ā ā
ā ā module.exports = { ... }; ā ā
ā ā }); ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
console.log('AMD Special Dependencies:');
// Simplified CommonJS wrapper in AMD
AMD.define('commonjs-style', [], function() {
// Simulating CommonJS-style module
const exports = {};
exports.greet = function(name) {
return `Hello, ${name}!`;
};
exports.VERSION = '1.0.0';
return exports;
});
AMD.require(['commonjs-style'], function(mod) {
console.log(' greet("AMD"):', mod.greet('AMD'));
console.log(' VERSION:', mod.VERSION);
});
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// PART 3: UMD (UNIVERSAL MODULE DEFINITION)
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā UMD PATTERN ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā UMD = Universal Module Definition ā
ā Works in: CommonJS (Node.js), AMD (RequireJS), and Browser Globals ā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā (function(root, factory) { ā ā
ā ā if (typeof define === 'function' && define.amd) { ā ā
ā ā // AMD ā ā
ā ā define(['dependency'], factory); ā ā
ā ā } else if (typeof module === 'object' && module.exports) { ā ā
ā ā // CommonJS ā ā
ā ā module.exports = factory(require('dependency')); ā ā
ā ā } else { ā ā
ā ā // Browser globals ā ā
ā ā root.MyModule = factory(root.Dependency); ā ā
ā ā } ā ā
ā ā })(this, function(dependency) { ā ā
ā ā return { /* module contents */ }; ā ā
ā ā }); ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
// UMD Pattern Example
(function(root, factory) {
// Check for AMD
if (typeof AMD !== 'undefined' && AMD.define) {
AMD.define('umdModule', [], factory);
}
// Check for CommonJS (Node.js)
else if (typeof module === 'object' && module.exports) {
module.exports = factory();
}
// Browser globals
else {
root.UMDModule = factory();
}
})(typeof globalThis !== 'undefined' ? globalThis : this, function() {
// Module factory function
return {
name: 'UMD Module',
version: '1.0.0',
greet(name) {
return `Hello from UMD, ${name}!`;
},
calculate(a, b) {
return {
sum: a + b,
product: a * b,
difference: a - b
};
}
};
});
console.log('UMD Pattern:');
// Access via AMD
AMD.require(['umdModule'], function(umd) {
console.log(' UMD greet("World"):', umd.greet('World'));
console.log(' UMD calculate(5, 3):', umd.calculate(5, 3));
});
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// PART 4: COMMONJS VS ES MODULES DIFFERENCES
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
/*
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā COMMONJS VS ES MODULES ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā Feature ā CommonJS ā ES Modules ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāā⤠ā
ā ā Syntax ā require/exports ā import/export ā ā
ā ā Loading ā Synchronous ā Asynchronous ā ā
ā ā Structure ā Dynamic ā Static ā ā
ā ā When parsed ā Runtime ā Compile time ā ā
ā ā Binding ā Copy of value ā Live binding ā ā
ā ā Top-level await ā No ā Yes (ES2022) ā ā
ā ā Tree-shaking ā No ā Yes ā ā
ā ā Strict mode ā Optional ā Always ā ā
ā ā this ā module object ā undefined ā ā
ā ā File extension ā .js, .cjs ā .mjs, .js (type:module) ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
*/
console.log('CommonJS vs ES Modules - Key Differences:');
// 1. Value Copy vs Live Binding
console.log('\n 1. Value Copy (CommonJS) vs Live Binding (ES Modules):');
// CommonJS: exports a copy
const cjsCounter = (function() {
let count = 0;
return {
count: count, // This is a copy!
increment() {
count++;
return count;
}
};
})();
console.log(' CommonJS-style counter:', cjsCounter.count); // 0
cjsCounter.increment();
console.log(' After increment, exported count:', cjsCounter.count); // Still 0!
console.log(' Actual count via method:', cjsCounter.increment() - 1); // 1
// ES Modules would have live binding - the value updates automatically
// 2. Dynamic vs Static
console.log('\n 2. Dynamic (CommonJS) vs Static (ES Modules):');
console.log(' CommonJS: require() can be anywhere, conditional');
console.log(' ES Modules: import must be at top level');
// CommonJS allows:
/*
if (condition) {
const module = require('./module');
}
*/
// ES Modules require import() for dynamic:
/*
if (condition) {
const module = await import('./module');
}
*/
// 3. this binding
console.log('\n 3. this Binding:');
console.log(' CommonJS: this === exports (module object)');
console.log(' ES Modules: this === undefined');
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// PART 5: REAL-WORLD EXAMPLES
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
console.log('Real-World Module Examples:');
// Example 1: Node.js style HTTP module (CommonJS)
const httpModule = CommonJSSimulator.require((module) => {
const createServer = (handler) => {
return {
listen(port, callback) {
console.log(` Server listening on port ${port}`);
if (callback) callback();
}
};
};
const get = (url, options) => {
return Promise.resolve({ statusCode: 200, data: 'response' });
};
module.exports = { createServer, get };
});
console.log(' HTTP Module (CommonJS style):');
const server = httpModule.createServer((req, res) => {});
server.listen(3000);
// Example 2: Configuration Module
const configModule = CommonJSSimulator.require((module) => {
const env = process.env?.NODE_ENV || 'development';
const configs = {
development: {
apiUrl: 'http://localhost:3000',
debug: true
},
production: {
apiUrl: 'https://api.production.com',
debug: false
}
};
module.exports = configs[env] || configs.development;
});
console.log(' Config Module:', configModule);
console.log('');
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
// SUMMARY
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
console.log(`
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā COMMONJS & AMD - EXAMPLES COMPLETE ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£
ā ā
ā CommonJS (Node.js): ā
ā ⢠module.exports = {...} to export ā
ā ⢠require('./module') to import ā
ā ⢠Synchronous loading ā
ā ⢠Values are copied (not live) ā
ā ⢠Still widely used in Node.js ā
ā ā
ā AMD (RequireJS): ā
ā ⢠define(name, deps, factory) to define ā
ā ⢠require(deps, callback) to load ā
ā ⢠Asynchronous loading ā
ā ⢠Designed for browsers ā
ā ⢠Less common today (ES Modules preferred) ā
ā ā
ā UMD (Universal): ā
ā ⢠Works in both environments ā
ā ⢠Good for library distribution ā
ā ⢠Complex wrapper pattern ā
ā ā
ā Modern Recommendation: ā
ā ⢠Use ES Modules when possible ā
ā ⢠Node.js supports both (package.json "type": "module") ā
ā ⢠Bundlers handle interop ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
`);