node 中 module.exports 与 exports 有什么区别
Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 351
Author 回答者: shfshanyue
一句话:exports
是 module.exports
的引用,如果 exports
没有重赋值,则二者没有任何区别,原理就在于 CommonJS 的 module_wrapper
,compiledWrapper.call(thisValue, module.exports, require, module)
。
类似如下所示
const exports = module.exports;
那以下代码结果会如何导出?
module.exports = 100;
exports = 3;
很显然会导出 100,毕竟 exports
进行了重赋值。
那在 node 源码中如何实现的呢? 从源码里可以看出 exports 的实质
详见源码: https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L1252,可以看出符合猜想
众所周知,node 中所有的模块代码都被包裹在这个函数中
exports = module.exports(
function (exports, require, module, __filename, __dirname) {
exports.a = 3;
},
);
而以下源码指出,exports
是如何得来
const dirname = path.dirname(filename);
const require = makeRequireFunction(this, redirects);
let result;
// 从这里可以看出来 exports 的实质
const exports = this.exports;
const thisValue = exports;
const module = this;
if (requireDepth === 0) statCache = new Map();
if (inspectorWrapper) {
result = inspectorWrapper(
compiledWrapper,
thisValue,
exports,
require,
module,
filename,
dirname,
);
} else {
// 这里是模块包装函数
result = compiledWrapper.call(
thisValue,
exports,
require,
module,
filename,
dirname,
);
}
我们再对示例代码放在包裹函数中,最终导出结果如何一目了然
const exports = module.exports(
function (exports, require, module, __filename, __dirname) {
module.exports = 100;
exports = 3;
},
);