web-dev-qa-db-ja.com

Babel 6.xでデフォルトのエクスポート値をrequire()できない

Babel 5.xでは、次のコードを記述できます。

app.js

export default function (){}

index.js

require('babel/register');
require('./app')();

その後、node index.jsをエラーなしで実行できます。ただし、Babel 6.xを使用して、次のコードを実行します

index.es6.js

require('babel-core/register');
require('./app')();

エラーになります

require(...)は関数ではありません

なぜ知りたいですか?

77
XGHeaven

TL; DR

使用する必要があります

require('./app').default();

説明

Babel 5はexport defaultの互換性ハックを使用していました。モジュールにエクスポートが1つしか含まれておらず、それがデフォルトのエクスポートである場合、module.exportsに割り当てられました。したがって、たとえば、モジュールapp.js

export default function () {}

これに変換されます

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = function () {};

module.exports = exports["default"];

これはrequire- ing Babelでトランスパイルされたモジュールとの互換性のために(あなたがしているように)purely行われました。一貫性もありませんでした。モジュールに名前付きエクスポートとデフォルトエクスポートの両方が含まれている場合、require- dにはできません。

実際には、ES6モジュールの仕様によると、デフォルトのエクスポートは、名前がdefaultの名前付きエクスポートとno differentです。コンパイル時に静的に解決できるのは単なる構文糖なので、これは

import something from './app';

これと同じです

import { default as something } from './app';

そうは言っても、Babel 6はモジュールをトランスコンパイルするときに相互運用性のハックをやめることにしたようです。これで、モジュールapp.jsが次のように変換されます

'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

exports.default = function () {};

ご覧のとおり、module.exportsへの割り当てはこれ以上ありません。このモジュールをrequireするには、以下を行う必要があります

require('./app').default();
132
Igor Raush

上記の正しい答えをフォローアップするだけです。

babel@5のデフォルトのエクスポート動作を使用する場合は、 babel-plugin-add-module-exports pluginを試すことができます。

それは私にとって非常にうまく機能しています。

7
haotang