节点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
答案 0 :(得分:271)
问题在于
在撰写本文时,没有任何环境本身支持ES6模块。在Node.js中使用它们时,您需要使用Babel之类的东西将模块转换为CommonJS。但究竟是怎么发生的?
许多人认为module.exports = ...
等同于export default ...
,exports.foo ...
等同于export const foo = ...
。但这并不完全正确,或者至少不是巴贝尔如何做到这一点。
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
。
答案 1 :(得分:10)
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()
答案 2 :(得分:1)
您需要在项目中正确配置babel才能使用export default和export const foo
npm install --save-dev @babel/plugin-proposal-export-default-from
然后在.babelrc中添加以下配置
"plugins": [
"@babel/plugin-proposal-export-default-from"
]
答案 3 :(得分:-27)
tl; dr现在为了这个工作,需要或导入SlimShady
的文件必须使用带有'use strict'
的Babel进行编译。
我在最初遇到此错误的项目中使用babel-cli
6.18.0。
'use strict'
是坏消息熊var SlimShady = require('./slim-shady');
var marshall = new SlimShady(); // uh, oh...
'use strict'
import SlimShady from './slim-shady'
var marshall = new SlimShady() // all good in the hood