CommonJS 功能介绍
CommonJS是JavaScript的模块化规范,主要用于服务器端(如Node.js)的模块化开发,其核心功能和特点如下:
一、核心功能
-
模块定义与导出
module.exports
:用于导出模块的内容,可以是函数、对象、变量等。例如:module.exports = function(a, b) { return a + b; }; // 导出单个函数 module.exports = { add, subtract }; // 导出多个方法[^1^][^4^]
exports
:module.exports
的简写引用,用于简化导出操作。例如:exports.sayHello = function(name) { return `Hello, ${name}`; }; [^4^]```
-
模块导入
require()
:同步导入模块并返回其导出的内容。例如:const math = require('./math'); // 导入整个模块 const { add } = require('./math'); // 解构导入[^1^][^4^]
二、关键特点
-
同步加载
- 模块加载是同步的,执行
require
时会阻塞后续代码,直到模块加载完成。适用于服务器端本地文件加载(速度快),但不适合浏览器环境[1][4]。
- 模块加载是同步的,执行
-
单例模式与缓存
- 每个模块在首次加载后会被缓存,后续
require
同一模块直接返回缓存实例。例如:const moduleA = require('./module'); const moduleB = require('./module'); console.log(moduleA === moduleB); // true[^1^][^4^]
- 每个模块在首次加载后会被缓存,后续
-
动态导入
- 支持运行时动态加载模块,根据条件灵活导入不同模块。例如:
if (condition) {const moduleA = require('./moduleA'); } else {const moduleB = require('./moduleB'); }[^1^][^4^]
- 支持运行时动态加载模块,根据条件灵活导入不同模块。例如:
-
文件即模块
- 每个文件视为独立模块,拥有单独的作用域,避免全局变量污染[2][4]。
三、模块加载机制
-
加载流程
- 路径解析:优先从缓存中查找模块;若未缓存,则检查是否为核心模块(如
fs
);否则按路径查找文件模块[4]。 - 文件扩展名:自动按
.js
、.json
、.node
顺序补全后缀[2]。 - 编译与执行:加载后立即编译并执行模块代码[4]。
- 路径解析:优先从缓存中查找模块;若未缓存,则检查是否为核心模块(如
-
循环依赖处理
- 通过缓存机制解决循环依赖,但需注意模块的加载顺序和状态[3][4]。
四、应用场景
-
服务器端开发
- Node.js默认使用CommonJS,适合后端代码的组织与管理。例如,通过
require
引入数据库驱动、路由模块等[1][4]。
- Node.js默认使用CommonJS,适合后端代码的组织与管理。例如,通过
-
前端开发
- 需通过构建工具(如Webpack、Browserify)将CommonJS模块转换为浏览器兼容格式。例如:
# 使用Webpack打包 webpack --entry ./src/index.js --output ./dist/bundle.js [^5^]
- 需通过构建工具(如Webpack、Browserify)将CommonJS模块转换为浏览器兼容格式。例如:
五、与ES模块(ESM)的对比
特性 | CommonJS | ES模块(ESM) |
---|---|---|
语法 | require() 、module.exports | import 、export |
加载方式 | 同步加载(阻塞) | 异步加载(非阻塞) |
动态导入 | 支持require() 动态加载 | 需使用import() 返回Promise |
缓存机制 | 模块单例缓存 | 无默认缓存(可通过import 实现) |
适用环境 | 服务器端(Node.js) | 浏览器端、现代前端工程 |
静态分析 | 不支持(运行时解析) | 支持(编译时优化) |
六、总结
CommonJS通过同步加载、单例缓存和简单的API设计,成为服务器端JavaScript模块化的事实标准。虽然ES模块在现代前端开发中更受青睐,但在Node.js生态和旧项目中,CommonJS仍具有重要价值[1][4][5]。