web-dev-qa-db-ja.com

node.jsとES6のmodule.exportsとexportのデフォルト

ノードの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
186
Marty Chang

問題はあります

  • eS6モジュールがCommonJSでどのようにエミュレートされるか
  • モジュールのインポート方法

ES6からCommonJSへ

これを書いている時点では、ES6モジュールをネイティブにサポートしている環境はありません。 Node.jsでそれらを使用するときは、モジュールをCommonJSに変換するためにBabelのようなものを使用する必要があります。しかし、それはどのように正確に起こりますか?

多くの人がmodule.exports = ...export default ...に、exports.foo ...export const foo = ...に相当すると同等と見なしています。しかしそれは必ずしも真実ではない、あるいは少なくともBabelがどのようにそれをしているのかはそうではない。

ES6のdefaultエクスポートは、実際には named 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オブジェクトのプロパティになることがわかります。

モジュールをインポートする

モジュールをインポートする方法は2つあります。CommonJSを使用するか、ES6のimport構文を使用する。

あなたの問題: /あなたはこんなことをしていると思います:

var bar = require('./input');
new bar();

barにデフォルトのエクスポートの値が割り当てられることを期待しています。しかし、上の例でわかるように、デフォルトのエクスポートはdefaultプロパティに割り当てられています。

そのため、デフォルトのエクスポートにアクセスするには、実際に行う必要があります。

var bar = require('./input').default;

ES6モジュールの構文を使うと、

import bar from './input';
console.log(bar);

バベルはそれをに変換します

'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へのアクセスに変換されていることがわかります。

268
Felix Kling