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 = ...
。但这并不完全正确,至少巴别塔不是这样做的。
ES6 default
exports实际上也命名为 exports,除了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对这两者做了一个很好的比较,对于那些想知道如何与模块一起执行导出默认值的人来说。nodejs中的导出
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()
您需要在项目中正确配置babel以使用export default和export const foo
npm install --save-dev @babel/plugin-proposal-export-default-from
然后在.babelrc
中添加下面的配置"plugins": [
"@babel/plugin-proposal-export-default-from"
]