Node.js - module.exports 与 exports 的区别

简而言之 exports是 module.exports本地文件中的快捷方式(相当于引用),它不能很好的实现导出功能。

a.js

exports.f = 123123

b.js

const a = require('./a');
console.log(a.f);

这样可以正常从a导出,在b.js中引用
a.js中改为exports = {f: 123}无法导出
a.js中改为module.exports = {f: 123}正常导出

以下为官方文档翻译:

module.exports#

Added in: v0.1.16

  • <Object>
    module.exports对象是由Module系统创建的,有时这是不能被接受的;很多人希望他们的module是一些class的实例。为此,将期望导出的对象赋值到module.exports。需要注意的是赋值期望的对象到exports会简单的将本地exports变量重新绑定,这很可能并不是所期望的结果。

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 to module.exports. Note that assigning the desired object to exports will simply rebind the local exports variable, which is probably not what is desired.

举个例子,假设我们建了一个叫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赋值必须立即执行,而不能在回调中进行,以下为错误示例:

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变量在模块的文件级范围内是有效的,并且会在模块评估之前被赋值为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 of module.exports before the module is evaluated.

It allows a shortcut, so that module.exports.f = ... can be written more succinctly as exports.f = .... However, be aware that like any variable, if a new value is assigned to exports, it is no longer bound to module.exports:

module.exports.hello = true; // Exported from require of module 从需求模块中导出
exports = { hello: false };  // Not exported, only available in the module 没有导出,仅在模块中有效

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()的假想实现(比实际简单很多):
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;
}

原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 今天被携程....幼师...打孩子.....喂芥末......安眠药....这些关键词霸屏了。 微博,公众号,头条...
    菲凡说阅读 637评论 0 49
  • 总有人错过一场梅雨 迷路在四月的柳絮 隔着千里暮霭找寻 天地不懂 总有人拜了一路的庙宇 只求一场精打细算的相遇 纵...
    胡子不归阅读 516评论 0 6
  • 滴滴的雨,微微的风,开着小窗,宿舍四处凉爽。 三人已睡,呼声四起,伴随着风,参杂着雨,我却毫无睡意。 抬起手机,简...
    古德曼here阅读 232评论 0 2
  • GCC: GNU Compiler CollectionGCC属于传统编译器,传统编译器的工作原理基本上都是三段...
    IRONYT阅读 4,241评论 0 1
  • 《郭靖黄蓉》 英雄少年思家国 蓉女佳人最婀娜 桃花岛上双雕落 星云梦里羡黄郭 《七夕》 星云河汉雨细细 牵牛织女影...
    人间正道是沧桑lq阅读 224评论 0 0