commonjs模块导出本质是给module.exports赋值,可直接导出函数或挂载为对象属性;支持动态扩展、命名导出及与es模块兼容写法,但需避免exports重赋值。

CommonJS 的模块导出本质是给 module.exports 赋值,函数本身可作为值直接导出,也可挂载为对象属性实现灵活扩展。
直接导出单个函数
最简洁的方式:把函数直接赋给 module.exports,调用方通过 require() 得到的就是该函数本身。
例如:
function add(a, b) {
return a + b;
}
module.exports = add;
使用时:
const add = require('./math');
console.log(add(2, 3)); // 5
导出多个函数(命名导出)
将函数作为属性挂在 module.exports 对象上,适合提供一组相关功能。
- 保持命名清晰,避免污染顶层作用域
- 支持解构或按名调用,便于维护和测试
- 可随时增减方法,不影响已有调用方式
例如:
utils.jsfunction formatDate(date) { /* ... */ }
function debounce(fn, delay) { /* ... */ }
function deepClone(obj) { /* ... */ }
<p>module.exports = {
formatDate,
debounce,
deepClone
};</p>
使用时:
const { debounce, deepClone } = require('./utils');
// 或
const utils = require('./utils');
utils.debounce(...);
动态扩展导出对象
在模块内部可后续向 module.exports 添加属性,适合运行时注册、插件式扩展。
- 适用于框架或工具库的插件机制(如中间件注册)
- 注意:必须在
require()完成前完成扩展,否则调用方可能获取不到新属性 - 避免在异步回调中修改导出对象,易引发竞态
例如(简易插件模式):
plugin-host.jsmodule.exports = {
plugins: [],
use(plugin) {
this.plugins.push(plugin);
}
};
<p>// 后续扩展(同步场景下安全)
module.exports.register = function(name, fn) {
this[name] = fn;
};</p>
兼容 ES 模块的写法(Node.js v14+)
若项目同时支持 CommonJS 和 ES 模块,可通过 exports 对象双写,但需注意:
-
exports是module.exports的快捷引用,修改其属性有效,重新赋值无效 - 不建议混用
export default和module.exports,会破坏互操作性 - 推荐统一用
module.exports,保证行为确定
正确示例:
// ✅ 可以
exports.add = (a, b) => a + b;
exports.mul = (a, b) => a * b;
<p>// ❌ 不推荐(覆盖 exports 会断开与 module.exports 的关联)
exports = { add: () => {} };</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











