Node.js和ES6中的module.exports与export默认值

Mar*_*ang 246 module node.js ecmascript-6

Node module.exports和ES6有什么区别export default?我试图找出当我尝试export default在Node.js 6.2.2中时为什么我得到"__不是构造函数"错误.

什么有效

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This works
module.exports = SlimShady
Run Code Online (Sandbox Code Playgroud)

什么工作

'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
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 332

问题在于

  • 如何在CommonJS中模拟ES6模块
  • 如何导入模块

ES6到CommonJS

在撰写本文时,没有任何环境本身支持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; 
Run Code Online (Sandbox Code Playgroud)

在这里我们可以看到默认导出成为exports对象上的属性,就像foo.

导入模块

我们可以通过两种方式导入模块:使用CommonJS或使用ES6 import语法.

你的问题:我相信你做的事情如下:

var bar = require('./input');
new bar();
Run Code Online (Sandbox Code Playgroud)

期望为其bar分配默认导出的值.但正如我们在上面的示例中所看到的,默认导出被分配给default属性!

因此,为了访问默认导出,我们实际上必须这样做

var bar = require('./input').default;
Run Code Online (Sandbox Code Playgroud)

如果我们使用ES6模块语法,即

import bar from './input';
console.log(bar);
Run Code Online (Sandbox Code Playgroud)

巴别塔会把它改造成

'use strict';

var _input = require('./input');

var _input2 = _interopRequireDefault(_input);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

console.log(_input2.default);
Run Code Online (Sandbox Code Playgroud)

您可以看到每次访问bar都转换为访问权限.default.

  • @Bergi:我没有搜索tbh(对我很可耻:()。对于相同的问题肯定有疑问,但是以不同的方式提出。让我知道您是否找到合适的东西! (2认同)
  • 我们如何导出默认值和命名值,以便这两个值都可以在客户端代码端工作: `ES6` -> `import library, { a, b, c } from "library"; `, `commonJS` -> `const 库 = require("库"); const { a, b, c } = require("库")`? 就像 `React` 一样,当使用 ES6 时,我们可以执行 `import React, { useEffect, useState } from "react";` ,而当使用 commonJS 时,我们可以执行 `const React = require("react"); const { useEffect, useState } = require("react");`...在编写我们自己的库时如何实现相同的目标?谢谢你! (2认同)

moe*_*imi 23

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()
Run Code Online (Sandbox Code Playgroud)