🧠 什么是模块化?
想象一下你正在组装一台复杂的乐高积木模型。如果你把所有的积木块都混在一起,试图一次性完成整个模型,这不仅会非常混乱,而且一旦出错,找到问题所在也会变得异常困难。相反,如果你将模型分解成几个独立的小部分(比如车身、车轮、车门等),然后逐一构建这些小部分,最后再组合起来,事情就会变得简单得多。
模块化就像是这种分而治之的思想在编程中的应用。它指的是将一个大型的应用程序分解成多个独立的、可以互相协作的小模块。每个模块就像一个独立的小积木块,专注于完成特定的任务,并通过定义良好的接口与其他模块进行交互。
💡模块化的类比:
- 餐厅厨房:想象一家餐厅的厨房,有专门负责切菜的厨师、负责烹饪的厨师和负责装盘的服务员。每个人都有明确的任务,但他们的工作又紧密相关,最终一起完成了美味佳肴。
- 家庭装修:当你装修房子时,你会分别请电工、水管工、油漆工等专业人士来做各自擅长的工作。每个专业人员只负责他们的一部分,最后所有的工作成果组合在一起,形成一个完整的家。
📚模块化的好处:
- 代码复用:编写一次,到处使用。就像你可以用同样的模具做出很多相同的蛋糕。
- 易于维护:小而专注的模块更易于理解和修改。就像修理一辆汽车时,只需更换有问题的部分,而不是重做整辆车。
- 提高性能:仅加载必要的模块,减少不必要的资源消耗。就像点餐时只点你需要的菜品,而不是每样都要一份。
- 简化测试:独立的模块更容易进行单元测试。就像检查一道菜的味道时,只需品尝这一道菜,而不是整桌饭菜。
JavaScript 模块化是组织代码的重要方式。随着 JavaScript 的发展,出现了两种主流模块系统:
- CommonJS(Node.js 默认)
- ES6 Modules(现代标准)
下面我将从语法、加载机制、适用环境等方面进行详细对比。
1️⃣ CommonJS(Node.js 默认使用)
✅ 基本用法
javascript
// 导出模块
// math.js
function add(a, b) {
return a + b;
}
module.exports = { add };
javascript
// 引入模块
// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 输出 5
🔁 加载机制:同步加载
require()
是同步的,会阻塞后续代码直到模块加载完成。- 适用于服务器端(如 Node.js),因为文件都在本地磁盘上,加载速度快。
📁 文件扩展名
- 使用
.js
扩展名。 - Node.js 默认使用 CommonJS 模块系统。
2️⃣ ES6 Modules(现代标准)
✅ 基本用法
javascript
// 导出模块
// math.js
export function add(a, b) {
return a + b;
}
javascript
// 引入模块
// app.js
import { add } from './math.js';
console.log(add(2, 3)); // 输出 5
🔁 加载机制:异步加载(默认行为)
- ES6 Modules 是静态导入,模块结构在编译阶段就确定了。
- 支持更好的优化(如 Tree Shaking)。
- 更适合浏览器环境。
⚠️ 注意事项(非常重要)
❗ node
默认情况下 .js
文件不支持 import
,但node
的最新版本已经支持了,意味着node
准备跟require commonJS
说再见了 , es6 module
是未来。
这是很多新手容易踩坑的地方!
✅ 启用 ES6 Modules 的方法
方法一:设置 "type": "module"
(推荐)
在项目根目录下的 package.json
中添加:
json
{
"type": "module"
}
这样,所有 .js
文件都将被视为 ES6 模块。
⚠️ 设置后不能再使用
require()
,否则会报错。
方法二:使用 .mjs
扩展名
如果你不想修改 package.json
,可以将模块文件命名为 .mjs
,例如:
math.mjs
app.mjs
Node.js 会自动识别这些文件为 ES6 模块。
✅ 示例:
javascript
// math.mjs
export function add(a, b) {
return a + b;
}
javascript
// app.mjs
import { add } from './math.mjs';
console.log(add(2, 3)); // 输出 5
📊 模块化对比表
特性 | CommonJS(require) | ES6 Modules(import) |
---|---|---|
加载方式 | 同步 | 异步 |
默认支持 | ✅ 在 Node.js 中默认支持 | ❌ 需配置或使用 .mjs |
是否推荐 | ❌ 已逐渐被替代 | ✅ 是未来趋势 |
文件扩展名 | .js |
.mjs 或通过 "type": "module" |
动态导入支持 | ❌ 不支持 | ✅ 支持 import() 动态导入 |
可读性 & 规范 | 老旧语法,不够规范 | 更清晰、标准化 |
💡 实用建议(新手必看)
场景 | 推荐使用 |
---|---|
写前端项目(React/Vue/Angular) | ✅ ES6 Modules(import/export) |
Node.js 小工具/脚本项目 | ✅ CommonJS(简单易用) |
Node.js 大型项目 / 现代项目 | ✅ ES6 Modules(配合 "type": "module" ) |
想同时使用? | ❌ 不建议混用,容易混乱,选择一种风格坚持到底 |
🎯 总结一句话:
CommonJS 是过去式,ES6 Modules 是未来趋势。在新项目中尽量使用 ES6 Modules,并注意启用方式(设置
"type": "module"
或使用.mjs
)。