node.js 和 ES6 中的 module.exports 与 export 默认值 [英] module.exports vs. export default in Node.js and ES6

查看:37
本文介绍了node.js 和 ES6 中的 module.exports 与 export 默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Node 的 module.exports 和 ES6 的 export default 有什么区别?我试图弄清楚为什么我在 Node.js 6.2.2 中尝试 export default 时会收到__ is not a constructor"错误.

What is the difference between Node's module.exports and ES6's export default? I'm trying to figure out why I get the "__ is not a constructor" error when I try to export default in Node.js 6.2.2.

'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

推荐答案

问题出在

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

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

At the time of writing this, no environment supports ES6 modules natively. When using them in Node.js you need to use something like Babel to convert the modules to CommonJS. But how exactly does that happen?

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

Many people consider module.exports = ... to be equivalent to export default ... and exports.foo ... to be equivalent to export const foo = .... That's not quite true though, or at least not how Babel does it.

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

ES6 default exports are actually also named exports, except that default is a "reserved" name and there is special syntax support for it. Lets have a look how Babel compiles named and default exports:

// 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 一样.

Here we can see that the default export becomes a property on the exports object, just like foo.

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

We can import the module in two ways: Either using CommonJS or using ES6 import syntax.

您的问题:我相信您正在执行以下操作:

Your issue: I believe you are doing something like:

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

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

expecting that bar is assigned the value of the default export. But as we can see in the example above, the default export is assigned to the default property!

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

So in order to access the default export we actually have to do

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

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

If we use ES6 module syntax, namely

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

Babel 会将其转换为

Babel will transform it to

'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.

You can see that every access to bar is converted to access .default.

这篇关于node.js 和 ES6 中的 module.exports 与 export 默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆