1. CommonJS Module Specification CommonJS defines how modules are referenced, defined, and identified.
1.1 Module Referencing Modules are imported using the require function:
const fs = require('fs'); 1.2 Module Definition Modules can export functions or variables through the exports object:
// add.js exports.add = function(a, b) { return a + b; }; To import in another file:
const { add } = require('./add.js'); console.log(add(1, 2)); // Outputs 3 1.3 Module Identification Module identifiers can be strings, relative paths, or absolute paths, helping to prevent variable pollution.
2. Node.js Module Implementation Node.js implements CommonJS with three key steps in module loading:
Path analysis File location Compilation and execution Core Concepts Core Modules: Built-in modules like fs, http. File Modules: User-created modules. Core modules are pre-compiled, allowing faster access than dynamically loaded file modules.
2.1 Loading from Cache Node.js caches modules after their first load, improving performance. Subsequent requests retrieve modules from cache.
2.2 Path Analysis and File Location Handled by Module._resolveFilename, which determines the full path of a module based on its identifier. It checks core modules, relative paths, and searches in node_modules.
2.3 Compilation and Execution Node.js compiles files based on their extensions:
JavaScript Files: Read and executed. JSON Files: Read and parsed. C/C++ Extensions: Loaded with process.dlopen. 3. Advanced Module Management 3.1 Dynamic Imports Node.js supports dynamic imports using the import() function for asynchronous module loading:
import('./module.js') .then((module) => { module.doSomething(); }) .catch((err) => { console.error('Failed to load module:', err); }); 3.2 ES Modules (ESM) Node.js also supports ESM, introducing a standardized module system. ESM allows static imports and uses export and import syntax.
Example of ESM syntax:
export const foo = 'bar'; export function doSomething() {} 4. Best Practices Consistent Module Format: Use either CommonJS or ESM. Use package.json: Define entry points and module types clearly. Leverage Caching: Optimize performance. Avoid require.extensions: Not recommended for production. Conclusion Node.js's module system, rooted in CommonJS, is robust and flexible, enabling efficient server-side JavaScript development. Understanding module loading, caching, and resolution is crucial for optimizing performance and maintainability in Node.js applications.