导出的快捷方式


exports 变量在模块的文件级作用域内可用,并在评估模块之前被分配 module.exports 的值。

它允许一个快捷方式,以便 module.exports.f = ... 可以更简洁地写成 exports.f = ...。 但是,请注意,与任何变量一样,如果将新值分配给 exports,则它就不再绑定到 module.exports

module.exports.hello = true; // 从模块的 require 中导出
exports = { hello: false };  // 未导出,仅在模块中可用

module.exports 属性被新对象完全替换时,通常也会重新分配 exports

module.exports = exports = function Constructor() {
  // ... 等等。
};

为了阐明该行为,想象一下 require() 的这个假设实现,它与 require() 的实际实现非常相似:

function require(/* ... */) {
  const module = { exports: {} };
  ((module, exports) => {
    // 模块代码在这里。 在本例中,定义一个函数。
    function someFunc() {}
    exports = someFunc;
    // 此时,exports 不再是 module.exports 的快捷方式,
    // 并且此模块仍然会导出空的默认对象。
    module.exports = someFunc;
    // 此时,该模块现在将导出 someFunc,
    // 而不是默认对象。
  })(module, module.exports);
  return module.exports;
}

The exports variable 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

When the module.exports property is being completely replaced by a new object, it is common to also reassign exports:

module.exports = exports = function Constructor() {
  // ... etc.
};

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;
}