红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules)
红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules)
资料取自《JavaScript高级程序设计(第5版)》。
查看总目录:红宝书学习大纲
一、模块化的意义:分而治之
模块化解决代码依赖混乱、命名冲突问题,核心思想:
- 每个文件为一个独立模块
- 导出(export)需要暴露的功能
- 导入(import)其他模块的功能
二、CommonJS:服务端的模块化方案
CommonJS设计用于服务器环境(如Node.js),特性:
示例1:导出对象
// math.js
function add(a, b) { return a + b; }
module.exports = { add }; // 导出模块功能 [^5]
// main.js
const math = require('./math.js'); // 导入模块 [^6]
console.log(math.add(3, 5)); // 输出8
示例2:导出类或实例
// User.js
class User { /* ... */ }
module.exports = User; // 导出类 [^5]
// app.js
const User = require('./User.js');
const user = new User();
关键特点:导出的是对象或值的拷贝,多次导入会缓存结果 [3]
三、ES Modules(ESM):原生的浏览器支持
ES Modules是JavaScript官方标准,特性:
示例3:基本语法
// math.js
export const multiply = (a, b) => a * b;
// main.js
import { multiply } from './math.js';
console.log(multiply(3, 5)); // 输出15
示例4:导出默认值
// config.js
const API_KEY = '12345abc';
export default API_KEY; // 默认导出
// app.js
import key from './config.js'; // 默认导入不使用大括号
关键特点:导出的是引用,动态绑定,值更新影响所有导入方 [3:2]
四、对比CommonJS与ES Modules
| 特征 | CommonJS | ES Modules |
|---|---|---|
| 运行环境 | Node.js(服务器端)[1:1] | 浏览器原生支持+现代Node [4:1] |
| 加载方式 | 同步(立即执行)[1:2] | 异步(按需加载)[3:3] |
| 导出内容 | 值的拷贝(静态)[2:1] | 值的引用(动态)[3:4] |
| 语法 | module.exports / require |
export / import |
五、现代工具链:模块打包与转换
由于浏览器兼容问题,常用工具:
- Webpack/Babel → 将ESM/CommonJS转为兼容代码 [^3]
- SystemJS → 动态加载多种格式模块(包括ESM)[^3]
flowchart TD
原始代码(ES6/CommonJS) --> Webpack
Webpack --> 合并为单一打包文件
打包文件 --> 浏览器运行
目录:总目录
上篇文章:红宝书第二十讲:详解JavaScript的Proxy与Reflect
脚注
《JavaScript高级程序设计(第5版)》详解CommonJS语法与Node.js的关系 ↩︎ ↩︎ ↩︎
《JavaScript高级程序设计(第5版)》演示CommonJS导出类与实例的方式 ↩︎ ↩︎
《JavaScript高级程序设计(第5版)》的目录指明ES Modules为原生标准 ↩︎ ↩︎

浙公网安备 33010602011771号