答案是:历史原因。
你说得对,我们可能只有module
和exports
不会被需要,但它仍然是为了向后兼容。
它曾经是模块包装器在几乎每个补丁版本中都发生变化的时候。
在节点0.1.11模块封装为:
var wrapper = "function (__filename) { "+
" var onLoad; "+
" var onExit; "+
" var exports = this; "+
content+
"\n"+
" this.__onLoad = onLoad;\n"+
" this.__onExit = onExit;\n"+
"};\n";
参见:https://github.com/nodejs/node/blob/v0.1.11/src/node.js#L167#L177
正如你可以看到exports
是一样的this
的包装函数被调用。您无法将其与新对象交换,甚至无法为其添加一些保留键 - 例如,您无法安全地导出名为__onExit
的属性。
然后在0.1.12是:
var wrapper = "function (__filename, exports) { " + content + "\n};";
参见:https://github.com/nodejs/node/blob/v0.1.12/src/node.js#L243-L245
这里exports
是作为一个参数提供的对象,但你不能用一个新的对象换了,你只能添加或删除你得到的对象的属性。
然后0.1.13是第一个具有此,即require
和include
:
var wrapper = "function (__filename, exports, require, include) { " + content + "\n};";
参见:https://github.com/nodejs/node/blob/v0.1.13/src/node.js#L225-L227
然后0.1.14是第一个具有__module
(用下划线)在包装(和下降include
):
var wrapper = "var __wrap__ = function (__module, __filename, exports, require) { "
+ content
+ "\n}; __wrap__;";
见:https://github.com/nodejs/node/blob/v0.1.14/src/node.js#L280-L284
而0.1。16是第一个在纸上出现module
参数(不带下划线):
var wrapper = "var __wrap__ = function (exports, require, module, __filename) { "
+ content
+ "\n}; __wrap__;";
参见:https://github.com/nodejs/node/blob/v0.1.16/src/node.js#L444-L448
它之后已经改变了很多次,但这个就是module
得到了介绍制作时间该exports
不再需要更多的,但仍然有用的快捷方式,让您的使用:的
exports.a = 1;
exports.b = 2;
exports.c = 3;
代替:
module.exports.a = 1;
module.exports.b = 2;
module.exports.c = 3;
但实际上如果没有exports
然后一个通常会写:
const exports = module.exports;
exports.a = 1;
exports.b = 2;
exports.c = 3;
或更可能:
module.exports = {
a: 1,
b: 2,
c: 3,
};
,或者有在静态分析工具进行一些检查:
const a = 1;
const b = 2;
const c = 3;
module.exports = { a, b, c };
有很多方法可以做到这一点,它很漂亮灵活的机制。
打败我吧。比我想起的还早。 – OrangeDog