区别 module.exports 与 exports

既生瑜,何生亮

Node.js 模块里,我们经常见着 module.exportsexports。二者区别在哪?

新建一个 module.cjs 文件:

console.log(exports === module.exports)

console.log(exports)

然后在命令行下运行 node module.cjs

$ node module.js
true
{}

=== 判断结果为 true。可见二者是一样的。实际上,是模块初始化时,exports 被赋予了 module.exports 的初始值,类似如下:

module.exports = {}
exports = module.exports

那么为什么要有两种写法?

CommonJS

CommonJS 的规范里,实际上并没有定义 module.exports,是 Node.js 加进去的。这也是为什么 webpack 里将 Node.js 版的 CommonJS 叫做 CommonJS2

快捷方式

很显然,exports 的写法要比 module.exports 快一些,毕竟少打了 7 个字符:

exports.pi = 3.14
module.exports.pi = 3.14

但是,我们可以想见,某些情况下,这种快捷方式会出问题,比如:

exports = 3.14
// 这个数据并不能被外部模块使用到

这是因为在 Node.js 模块里,真正控制模块导出的是 module.exports,类似 exports = 3.14 这样的代码将 exportsmodule.exports 割离,此时的 exports,不再是快捷方式,而只是模块内的一个普通变量。

就我个人而言,我会尽量避免使用 exports,以减少不必要的误会。