簡而言之 exports是 module.exports本地文件中的快捷方式(相當(dāng)于引用),它不能很好的實現(xiàn)導(dǎo)出功能。
a.js
exports.f = 123123
b.js
const a = require('./a');
console.log(a.f);
這樣可以正常從a導(dǎo)出,在b.js中引用
a.js中改為exports = {f: 123}無法導(dǎo)出
a.js中改為module.exports = {f: 123}正常導(dǎo)出
以下為官方文檔翻譯:
module.exports#
Added in: v0.1.16
-
<Object>
module.exports對象是由Module系統(tǒng)創(chuàng)建的,有時這是不能被接受的;很多人希望他們的module是一些class的實例。為此,將期望導(dǎo)出的對象賦值到module.exports。需要注意的是賦值期望的對象到exports會簡單的將本地exports變量重新綁定,這很可能并不是所期望的結(jié)果。
The
module.exportsobject is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object tomodule.exports. Note that assigning the desired object toexportswill simply rebind the localexportsvariable, which is probably not what is desired.
舉個例子,假設(shè)我們建了一個叫a.js的模塊
For example suppose we were making a module called a.js
const EventEmitter = require('events');
module.exports = new EventEmitter();
// Do some work, and after some time emit
// the 'ready' event from the module itself.
// 搞點事情,過一秒之后將'ready'事件從模塊自身提交出去
setTimeout(() => {
module.exports.emit('ready');
}, 1000);
在另一個文件中我們可以這么做
Then in another file we could do
const a = require('./a');
a.on('ready', () => {
console.log('module a is ready');
});
要注意給module.exports賦值必須立即執(zhí)行,而不能在回調(diào)中進(jìn)行,以下為錯誤示例:
Note that assignment to module.exports must be done immediately. It cannot be done in any callbacks. This does not work:
x.js:
setTimeout(() => {
module.exports = { a: 'hello' };
}, 0);
y.js:
const x = require('./x');
console.log(x.a);
exports shortcut#
Added in: v0.1.16
exports變量在模塊的文件級范圍內(nèi)是有效的,并且會在模塊評估之前被賦值為module.exports的值
它允許有一個快捷鍵,所以module.exports.f = ...可以更簡潔的寫為exports.f = ...然而,要意識到,和其他變量一樣,假如有一個新的值被賦到exports上,那么它將不再綁定到module.exports:
The
exportsvariable is available within a module's file-level scope, and is assigned the value ofmodule.exportsbefore the module is evaluated.It allows a shortcut, so that
module.exports.f = ...can be written more succinctly asexports.f = ....However, be aware that like any variable, if a new value is assigned toexports, it is no longer bound tomodule.exports:
module.exports.hello = true; // Exported from require of module 從需求模塊中導(dǎo)出
exports = { hello: false }; // Not exported, only available in the module 沒有導(dǎo)出,僅在模塊中有效
當(dāng)module.exports屬性被完全替換為一個新的對象時,通常也會重新賦值exports,例如:
When the module.exports property is being completely replaced by a new object, it is common to also reassign exports, for example:
module.exports = exports = function Constructor() {
// ... etc.
};
為了闡明這個行為,猜想一下require()的假想實現(xiàn)(比實際簡單很多):
To illustrate the behavior, imagine this hypothetical implementation of require(), which is quite similar to what is actually done by require():
function require(/* ... */) {
const module = { exports: {} };
((module, exports) => {
// Module code here. In this example, define a function.
function someFunc() {}
exports = someFunc;
// At this point, exports is no longer a shortcut to module.exports, and
// this module will still export an empty default object.
module.exports = someFunc;
// At this point, the module will now export someFunc, instead of the
// default object.
})(module, module.exports);
return module.exports;
}