CommonJS 规范中关于module.exports导出语法的四大类常用总结
CommonJS 全部导出语法汇总
CommonJS 本质只有唯一出口:
module.exports,exports 只是它的初始引用别名,所有导出写法都是对这两个变量的操作变形,总共分为4 大类常用写法,附带原理、示例、优缺点,帮你彻底区分。前置核心原理(必记)
每个 Node 模块初始化时默认执行:
var module = { exports: {} };
var exports = module.exports; // 引用赋值,指向同一个空对象
模块最终向外暴露的永远是
module.exports 的值,require() 获取的就是它;一旦重新赋值 module.exports = xxx,会切断和 exports 的引用关系。一、写法 1:挂载属性导出(命名批量导出,最常用)
1. exports.xxx = 值(简写版)
// utils.js
exports.add = (a, b) => a + b;
exports.del = (a, b) => a - b;
exports.str = '测试字符串';
2. module.exports.xxx = 值(完整版,你上一轮提问的写法)
module.exports.add = (a, b) => a + b;
module.exports.del = (a, b) => a - b;
- 本质:给默认空导出对象追加属性,最终导出一个包含所有挂载属性的对象
- 导入:支持解构
const {add} = require('./utils') - 适用:导出多个函数、变量、常量
- 注意:不能后续重写
module.exports = 其他值,会覆盖所有挂载的属性
二、写法 2:直接重写 module.exports 整体导出(单值导出)
直接替换整个导出对象,抛弃默认的空对象,导出单个任意类型数据(函数、类、实例、数组、数字都可以)
导出单个函数
// calc.js
module.exports = function(a, b) { return a + b }
导出类 / 实例 / 数组 / 基本类型
// 导出类
module.exports = Person;
// 导出提前创建好的实例
module.exports = new Person('张三');
// 导出数组/字符串
module.exports = [1,2,3];
module.exports = 'hello';
- 导入:
const add = require('./calc')直接拿到这个值,无法解构 - 适用:模块只对外暴露一个核心功能(工具函数、单例实例、主类)
三、写法 3:一次性字面量对象批量导出(合并写法)
一次性给
module.exports 赋值一个对象字面量,批量定义多个导出成员module.exports = {
add: (a,b)=>a+b,
del: (a,b)=>a-b,
flag: true
}
- 等价于写法 1 逐行挂载的最终效果,只是写法集中化
- 导入:可解构
const {add, del} = require('./xxx') - 适用:提前规划好所有导出成员,统一编写
四、写法 4:混合组合导出(进阶混用,不推荐新手使用)
先通过
exports.xxx 挂载一部分属性,再整体重写 module.exports(会覆盖前面挂载内容)// 先挂载(会失效)
exports.add = () => 1+1;
// 整体重写出口,上面的add直接丢失
module.exports = {
del: () => 2-1
}
- 坑点:重写
module.exports后,exports还指向原来的空对象,再写exports.xxx不会生效 - 建议:项目中不要混用,要么全用挂载属性,要么直接整体导出
精简归类(总共 4 种语法,归类为 2 大逻辑)
- 追加属性模式(导出多个成员)
exports.xxx = xxxmodule.exports.xxx = xxxmodule.exports = { 键值对 }
- 整体替换模式(导出单个成员)
module.exports = 任意值(函数/类/实例/基础类型)
补充关键对比表
| 写法 | 导出结构 | 能否解构导入 | 最佳使用场景 |
|---|---|---|---|
exports.fn = xxx |
对象包含多个方法 | 可以 | 工具类多个小函数 |
module.exports.fn = xxx |
对象包含多个方法 | 可以 | 同上面,语义更完整 |
module.exports = {fn1,fn2} |
自定义对象 | 可以 | 统一批量定义导出 |
module.exports = 单独函数/类/实例 |
单个值 | 不可以 | 模块只有一个核心功能 |
总结
语法书写形式有 4 种,但底层只有两种导出逻辑:
- 不替换原始导出对象,往上面挂属性(多成员导出);
- 直接替换
module.exports整个出口(单成员导出)。日常开发优先选:多方法用exports.xxx,单核心功能用module.exports = xxx,尽量不混用。

浙公网安备 33010602011771号