全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-15 8 分钟 ✍️ juanwangdev

Node.js ES Modules 与 CommonJS 对比

Node.js 支持两种模块系统:CommonJS(原生)和 ES Modules(ES6 标准)。

CommonJS 基本语法

JavaScript
// 导出 - math.js
module.exports.add = (a, b) => a + b;
module.exports.subtract = (a, b) => a - b;

// 或
module.exports = { add, subtract };

// 引入 - app.js
const math = require('./math');
const { add, subtract } = require('./math');

ES Modules 基本语法

JavaScript
// 导出 - math.mjs
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

// 或
export { add, subtract };

// 默认导出
export default { add, subtract };

// 引入 - app.mjs
import { add, subtract } from './math.mjs';
import math from './math.mjs'; // 默认导出
import * as math from './math.mjs'; // 全部导入

核心差异对比

特性CommonJSES Modules
导出语法module.exportsexport
引入语法require()import
加载时机运行时(动态)解析时(静态)
文件扩展名.js, .cjs.mjs, .js(需配置)
值的复制值复制值引用(实时绑定)
thismodule.exportsundefined
顶层 await不支持支持

值绑定差异

JavaScript
// CommonJS - 值复制
// counter.js
let count = 0;
module.exports = {
  count,
  increment: () => ++count
};

// main.js
const counter = require('./counter');
console.log(counter.count); // 0
counter.increment();
console.log(counter.count); // 0(未更新)
JavaScript
// ES Modules - 值引用(实时绑定)
// counter.mjs
export let count = 0;
export function increment() {
  ++count;
}

// main.mjs
import { count, increment } from './counter.mjs';
console.log(count); // 0
increment();
console.log(count); // 1(实时更新)

启用 ES Modules

JavaScript
// 方式1:使用 .mjs 扩展名
// app.mjs
import fs from 'fs';

// 方式2:package.json 配置
{
  "type": "module"
}
// 然后使用 .js 扩展名即可

// 方式3:命令行指定
node --experimental-modules app.mjs

互操作性

在 ES Modules 中引入 CommonJS

JavaScript
// utils.cjs(CommonJS)
module.exports = { add: (a, b) => a + b };

// app.mjs(ES Module)
import utils from './utils.cjs'; // 作为默认导出
console.log(utils.add(1, 2));

// CommonJS 导出整体作为默认导出
// 不能直接 import { add } from './utils.cjs'

在 CommonJS 中引入 ES Modules

JavaScript
// math.mjs(ES Module)
export const add = (a, b) => a + b;

// app.cjs(CommonJS)
// 不能使用 require('./math.mjs')
// 需使用动态 import
const math = await import('./math.mjs');
console.log(math.add(1, 2));

循环依赖处理

JavaScript
// CommonJS:返回缓存副本
// a.js
const b = require('./b');
exports.a = 1;

// b.js
const a = require('./a'); // 得到未完成的 exports

// ES Modules:返回实时绑定
// a.mjs
import { b } from './b.mjs';
export let a = 1;

// b.mjs
import { a } from './a.mjs'; // 实时绑定

选择建议

场景推荐
Node.js 后端项目CommonJS(更兼容)
前端/全栈项目ES Modules(标准化)
需要动态加载CommonJS(require 可动态)
需要静态分析ES Modules(import 可分析)
TypeScript 项目ES Modules

要点总结

  • CommonJS 使用 require/module.exports,运行时加载
  • ES Modules 使用 import/export,静态解析
  • ES Modules 导出值是实时绑定,CommonJS 是值复制
  • CommonJS 可动态 require,ES Modules import 必须顶层
  • Node.js 推荐使用 CommonJS,新项目可用 ES Modules

📝 发现内容有误?点击此处直接编辑

← 上一篇 Node.js CommonJS 模块规范
下一篇 → Node.js npm 包管理
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库