Node.js 和 ES6 中的 module.exports 与 export default

新手上路,请多包涵

Node 的 module.exports 和 ES6 的 export default 什么区别?我试图弄清楚为什么我在 Node.js 6.2.2 中尝试 export default 时得到“__ 不是构造函数”错误。

什么有效

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This works
module.exports = SlimShady

什么 不起作用

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This will cause the "SlimShady is not a constructor" error
// if in another file I try `let marshall = new SlimShady()`
export default SlimShady

原文由 Marty Chang 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 683
2 个回答

问题在于

  • CommonJS 中如何模拟 ES6 模块
  • 你如何导入模块

ES6 到 CommonJS

在撰写本文时,没有任何环境原生支持 ES6 模块。在 Node.js 中使用它们时,您需要使用 Babel 之类的东西将模块转换为 CommonJS。但是这到底是怎么发生的呢?

很多人认为 module.exports = ... 等价于 export default ...exports.foo ... 等价于 export const foo = ... 。但这并不完全正确,或者至少不是 Babel 是如何做到的。

ES6 default 导出实际上也 被命名为 导出,除了 default 是一个“保留”名称并且有特殊的语法支持。让我们看看 Babel 是如何编译命名和默认导出的:

 // input
export const foo = 42;
export default 21;

// output
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = exports.foo = 42;
exports.default = 21;

在这里我们可以看到默认导出成为 exports 对象上的一个属性,就像 foo 一样。

导入模块

我们可以通过两种方式导入模块:使用 CommonJS 或使用 ES6 import 语法。

您的问题: 我相信您正在做类似的事情:

 var bar = require('./input');
new bar();

期望 bar 被分配默认导出的值。但正如我们在上面的示例中看到的,默认导出分配给了 default 属性!

所以为了访问默认导出,我们实际上必须做

var bar = require('./input').default;

如果我们使用 ES6 模块语法,即

import bar from './input';
console.log(bar);

Babel 会将其转换为

'use strict';

var _input = require('./input');

var _input2 = _interopRequireDefault(_input);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

console.log(_input2.default);

可以看到每次访问 bar 都转换为访问 .default

原文由 Felix Kling 发布,翻译遵循 CC BY-SA 3.0 许可协议

Felix Kling 对这两者做了很好的比较,对于任何想知道如何在 nodejs 中使用 module.exports 进行命名导出的导出默认值

module.exports = new DAO()
module.exports.initDAO = initDAO // append other functions as named export

// now you have
let DAO = require('_/helpers/DAO');
// DAO by default is exported class or function
DAO.initDAO()

原文由 moein rahimi 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题