node.js 和 ES6 中的 module.exports 与 export 默认值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40294870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
module.exports vs. export default in Node.js and ES6
提问by Marty Chang
What is the difference between Node's module.exportsand ES6's export default? I'm trying to figure out why I get the "__ is not a constructor" error when I try to export defaultin Node.js 6.2.2.
Nodemodule.exports和 ES6 有什么区别export default?我试图弄清楚为什么我export default在 Node.js 6.2.2 中尝试时会收到“__ 不是构造函数”错误。
What works
什么有效
'use strict'
class SlimShady {
constructor(options) {
this._options = options
}
sayName() {
return 'My name is Slim Shady.'
}
}
// This works
module.exports = SlimShady
What doesn'twork
什么不工作
'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
回答by Felix Kling
The issue is with
问题是
- how ES6 modules are emulated in CommonJS
- how you import the module
- 如何在 CommonJS 中模拟 ES6 模块
- 你如何导入模块
ES6 to CommonJS
ES6 到 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?
在撰写本文时,没有任何环境原生支持 ES6 模块。在 Node.js 中使用它们时,您需要使用类似 Babel 的工具将模块转换为 CommonJS。但这究竟是怎么发生的呢?
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.
很多人认为module.exports = ...相当于export default ...和exports.foo ...相当于export const foo = ...。但这并不完全正确,或者至少不是 Babel 是如何做到的。
ES6 defaultexports are actually also namedexports, except that defaultis a "reserved" name and there is special syntax support for it. Lets have a look how Babel compiles named and default exports:
ES6default导出实际上也是命名导出,只不过它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;
Here we can see that the default export becomes a property on the exportsobject, just like foo.
在这里我们可以看到默认导出变成了exports对象的一个属性,就像foo.
Import the module
导入模块
We can import the module in two ways: Either using CommonJS or using ES6 importsyntax.
我们可以通过两种方式导入模块:使用 CommonJS 或使用 ES6import语法。
Your issue:I believe you are doing something like:
你的问题:我相信你正在做这样的事情:
var bar = require('./input');
new bar();
expecting that baris assigned the value of the default export. But as we can see in the example above, the default export is assigned to the defaultproperty!
期望bar被分配默认导出的值。但是正如我们在上面的示例中看到的,默认导出已分配给default属性!
So in order to access the default export we actually have to do
所以为了访问默认导出,我们实际上必须做
var bar = require('./input').default;
If we use ES6 module syntax, namely
如果我们使用 ES6 模块语法,即
import bar from './input';
console.log(bar);
Babel will transform it to
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);
You can see that every access to baris converted to access .default.
可以看到,每个 accessbar都转换为 access .default。
回答by Hassan Azhar Khan
You need to configure babel correctly in your project to use export default and export const foo
您需要在项目中正确配置 babel 才能使用 export default 和 export const foo
npm install --save-dev @babel/plugin-proposal-export-default-from
then add below configration in .babelrc
然后在 .babelrc 中添加以下配置
"plugins": [
"@babel/plugin-proposal-export-default-from"
]
回答by moein rahimi
Felix Kling did a great comparison on those two, for anyone wondering how to do an export default alongside named exports with module.exports in nodejs
Felix Kling 对这两者进行了很好的比较,对于任何想知道如何在 nodejs 中使用 module.exports 与命名导出一起进行导出默认值的人
module.exports = new DAO()
module.exports.initDAO = initDAO // append other functions a named export
// now you have
let DAO = require('_/helpers/DAO');
// DAO by default is exported class or function
DAO.initDAO()
回答by Marty Chang
tl;dr right now for this to work, the file that is requiring or importing SlimShadymust be compiled using Babel with 'use strict'.
tl;dr 现在要让它工作,需要或导入的文件SlimShady必须使用 Babel 和'use strict'.
I'm using babel-cli6.18.0 in the project where I initially encountered this error.
我在babel-cli最初遇到此错误的项目中使用6.18.0。
Without 'use strict'is Bad News Bears
没有'use strict'是坏消息熊
var SlimShady = require('./slim-shady');
var marshall = new SlimShady(); // uh, oh...
'use strict', please
'使用严格',请
'use strict'
import SlimShady from './slim-shady'
var marshall = new SlimShady() // all good in the hood

