Node module.exports和ES6 之间有什么区别export default?我试图弄清楚为什么export default在Node.js 6.2.2中尝试出现“ __不是构造函数”错误。
module.exports
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
问题是
在撰写本文时,没有环境本地支持ES6模块。在Node.js中使用它们时,您需要使用Babel之类的东西将模块转换为CommonJS。但是那到底是怎么发生的呢?
许多人认为module.exports = ...等同于export default ...和exports.foo ...等同于export const foo = ...。但这不是真的,或者至少不是Babel是如何做到的。
module.exports = ...
export default ...
exports.foo ...
export const foo = ...
ES6 default导出实际上也 被称为 导出,只是它default是一个“保留”名称,并且对其有特殊的语法支持。让我们看一下Babel如何编译命名和默认导出:
default
// 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。
exports
foo
我们可以通过两种方式导入模块:使用CommonJS或使用ES6 import语法。
import
您的问题: 我相信您正在执行以下操作:
var bar = require('./input'); new bar();
期望为其bar分配默认导出的值。但正如我们在上面的示例中看到的那样,默认导出已分配给该default属性!
bar
因此,为了访问默认导出,我们实际上必须做
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。
.default