1. ホーム
  2. node.js

[解決済み] Node.jsとES6におけるmodule.exportsとexport defaultの比較

2022-03-22 12:30:52

質問

Nodeの module.exports とES6の export default ? を実行しようとすると、 "__ is not a constructor" というエラーが表示されるのはなぜでしょうか? 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

はありません。 働く

'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 = ... . しかし、それは全く正しくありませんし、少なくともBabelのやり方とは異なります。

ES6 default のエクスポートは、実は という名前 を除いては default はquot;reserved"の名前で、特別な構文がサポートされています。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 .