🎯 什么是模块化?CommonJS 和 ES6 Modules 到底有什么区别?小白也能看懂

0 阅读4分钟

🧠 什么是模块化?

想象一下你正在组装一台复杂的乐高积木模型。如果你把所有的积木块都混在一起,试图一次性完成整个模型,这不仅会非常混乱,而且一旦出错,找到问题所在也会变得异常困难。相反,如果你将模型分解成几个独立的小部分(比如车身、车轮、车门等),然后逐一构建这些小部分,最后再组合起来,事情就会变得简单得多。

模块化就像是这种分而治之的思想在编程中的应用。它指的是将一个大型的应用程序分解成多个独立的、可以互相协作的小模块。每个模块就像一个独立的小积木块,专注于完成特定的任务,并通过定义良好的接口与其他模块进行交互。

💡模块化的类比:

  • 餐厅厨房:想象一家餐厅的厨房,有专门负责切菜的厨师、负责烹饪的厨师和负责装盘的服务员。每个人都有明确的任务,但他们的工作又紧密相关,最终一起完成了美味佳肴。
  • 家庭装修:当你装修房子时,你会分别请电工、水管工、油漆工等专业人士来做各自擅长的工作。每个专业人员只负责他们的一部分,最后所有的工作成果组合在一起,形成一个完整的家。

📚模块化的好处:

  1. 代码复用:编写一次,到处使用。就像你可以用同样的模具做出很多相同的蛋糕。
  2. 易于维护:小而专注的模块更易于理解和修改。就像修理一辆汽车时,只需更换有问题的部分,而不是重做整辆车。
  3. 提高性能:仅加载必要的模块,减少不必要的资源消耗。就像点餐时只点你需要的菜品,而不是每样都要一份。
  4. 简化测试:独立的模块更容易进行单元测试。就像检查一道菜的味道时,只需品尝这一道菜,而不是整桌饭菜。

JavaScript 模块化是组织代码的重要方式。随着 JavaScript 的发展,出现了两种主流模块系统:

  • CommonJS(Node.js 默认)
  • ES6 Modules(现代标准)

下面我将从语法、加载机制、适用环境等方面进行详细对比。


1️⃣ CommonJS(Node.js 默认使用)

✅ 基本用法

// 导出模块
// math.js
function add(a, b) {
  return a + b;
}
module.exports = { add };
// 引入模块
// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 输出 5

🔁 加载机制:同步加载

  • require()同步的,会阻塞后续代码直到模块加载完成。
  • 适用于服务器端(如 Node.js),因为文件都在本地磁盘上,加载速度快。

📁 文件扩展名

  • 使用 .js 扩展名。
  • Node.js 默认使用 CommonJS 模块系统。

2️⃣ ES6 Modules(现代标准)

✅ 基本用法

// 导出模块
// math.js
export function add(a, b) {
  return a + b;
}
// 引入模块
// 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 中添加:

{
  "type": "module"
}

这样,所有 .js 文件都将被视为 ES6 模块。

⚠️ 设置后不能再使用 require(),否则会报错。


方法二:使用 .mjs 扩展名

如果你不想修改 package.json,可以将模块文件命名为 .mjs,例如:

  • math.mjs
  • app.mjs

Node.js 会自动识别这些文件为 ES6 模块。

✅ 示例:

// math.mjs
export function add(a, b) {
  return a + b;
}
// 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)。