Node.js中module.exports、exports、export、export default的区别是什么?
Hey there! Great question—this is one of the most common pitfalls when working with Node.js modules, especially if you're switching between the traditional CommonJS system and modern ES Modules. Let's break down each method clearly, with examples to avoid confusion.
一、CommonJS 系统:module.exports 和 exports
Node.js uses CommonJS as its default module system (unless you configure it for ES Modules). Every file is treated as a separate module, and Node automatically creates a module object for each one.
1. module.exports:真正的导出入口
This is the actual value that gets exported from your module. Whatever you assign to module.exports is what other files will receive when they require() your module.
Examples:
// 导出单个值 module.exports = "Hello, CommonJS!"; // 导出一个对象(最常见的用法) module.exports = { greet: () => console.log("Hi!"), version: 1.0, isActive: true }; // 导出一个函数 module.exports = function add(a, b) { return a + b; };
2. exports:module.exports 的快捷引用
exports is just a reference (pointer) to module.exports. Think of it as Node doing this behind the scenes:
let exports = module.exports;
This means you can add properties to exports and they'll show up in module.exports:
exports.greet = () => console.log("Hi!"); exports.version = 1.0; // 等同于 module.exports.greet = ...
Critical Gotcha!
If you reassign exports directly (instead of adding properties), you break the link to module.exports. The module will still export whatever module.exports points to, not your new exports object:
// ❌ 没用!exports现在指向新对象,和module.exports无关了 exports = { greet: () => console.log("Hi!") }; // ✅ 正确做法:直接修改module.exports,或者给exports加属性 module.exports = { greet: () => console.log("Hi!") };
3. 混用 module.exports 和 exports
If you assign a new value to module.exports after using exports, the exports reference becomes irrelevant—only the final module.exports value is exported:
exports.version = 1.0; module.exports = { greet: () => console.log("Hi!") }; // 导出的是 { greet: ... },version属性被丢弃了
二、ES Modules (ES6+):export 和 export default
ES Modules are the official ECMAScript standard for modules. To use them in Node.js, you need to:
- Add
"type": "module"to yourpackage.json - Or use the
.mjsfile extension
1. export:命名导出
Use this to export multiple named values from a module. You can export variables, functions, or classes directly, or export them later by name.
Examples:
// 直接导出 export const version = 1.0; export function greet() { console.log("Hello, ES Modules!"); } // 先定义,再导出(可以重命名) const isActive = true; export { isActive, version as moduleVersion };
When importing, you need to use the exact names (or rename them with as):
import { greet, moduleVersion } from "./my-module.js"; import { isActive as activeStatus } from "./my-module.js";
2. export default:默认导出
Each module can have only one default export. This is useful when you want to export a single main value (like a class, function, or object).
Examples:
// 直接导出默认值 export default "Hello, Default Export!"; // 导出默认函数 export default function() { console.log("Default function"); } // 先定义,再导出 const mainObject = { greet: () => console.log("Hi!") }; export default mainObject;
When importing, you can give the default export any name you want:
import myDefault from "./my-module.js"; import customName from "./my-module.js"; // 同样有效 // 同时导入默认和命名导出 import myDefault, { greet } from "./my-module.js";
三、核心区别总结
| 特性 | module.exports/exports | export/export default |
|---|---|---|
| 所属模块系统 | CommonJS (Node.js 默认) | ES Modules (标准) |
| 导出机制 | 动态导出(运行时确定) | 静态导出(编译时确定) |
| 导入方式 | 使用 require() | 使用 import 语句 |
| 多导出支持 | 需导出对象包含多个属性 | 原生支持多个命名导出 |
| 默认导出逻辑 | 直接赋值 module.exports | 用 export default 声明 |
内容的提问来源于stack exchange,提问作者luhua wu

