簡而言之 exports是 module.exports本地文件中的快捷方式(相當(dāng)于引用)棚瘟,它不能很好的實(shí)現(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
對(duì)象是由Module系統(tǒng)創(chuàng)建的,有時(shí)這是不能被接受的怜奖;很多人希望他們的module是一些class的實(shí)例。為此翅阵,將期望導(dǎo)出的對(duì)象賦值到module.exports歪玲。需要注意的是賦值期望的對(duì)象到exports
會(huì)簡單的將本地exports
變量重新綁定,這很可能并不是所期望的結(jié)果掷匠。
The
module.exports
object 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 toexports
will simply rebind the localexports
variable, which is probably not what is desired.
舉個(gè)例子滥崩,假設(shè)我們建了一個(gè)叫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.
// 搞點(diǎn)事情,過一秒之后將'ready'事件從模塊自身提交出去
setTimeout(() => {
module.exports.emit('ready');
}, 1000);
在另一個(gè)文件中我們可以這么做
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)行钙皮,以下為錯(cuò)誤示例:
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
變量在模塊的文件級(jí)范圍內(nèi)是有效的,并且會(huì)在模塊評(píng)估之前被賦值為module.exports
的值
它允許有一個(gè)快捷鍵顽决,所以module.exports.f = ...
可以更簡潔的寫為exports.f = ...
然而短条,要意識(shí)到,和其他變量一樣才菠,假如有一個(gè)新的值被賦到exports
上茸时,那么它將不再綁定到module.exports
:
The
exports
variable is available within a module's file-level scope, and is assigned the value ofmodule.exports
before 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
屬性被完全替換為一個(gè)新的對(duì)象時(shí)赋访,通常也會(huì)重新賦值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.
};
為了闡明這個(gè)行為缓待,猜想一下require()
的假想實(shí)現(xiàn)(比實(shí)際簡單很多):
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;
}