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
最佳答案
问题在于
- 如何在 CommonJS 中模拟 ES6 模块
- 如何导入模块
ES6 到 CommonJS
在撰写本文时,没有任何环境原生支持 ES6 模块。在 Node.js 中使用它们时,您需要使用 Babel 之类的东西将模块转换为 CommonJS。但这究竟是怎么发生的呢?
很多人认为 module.exports = ...
等同于 export default ...
和 exports.foo ...
等同于 export const foo = ...
。但这并不完全正确,或者至少不是 Babel 是如何做到的。
ES6 default
导出实际上也是 named 导出,除了 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
。
关于node.js - Node.js 和 ES6 中的 module.exports 与 export default,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40294870/