Babel 6はデフォルトのエクスポート方法を変更します


195

以前は、babelが行を追加していましたmodule.exports = exports["default"]。これはもう行われません。これが意味することは、私ができる前のことです。

var foo = require('./foo');
// use foo

今私はこれをしなければなりません:

var foo = require('./foo').default;
// use foo

大したことではありません(そして、これはそれがずっとあったはずのことだと私は推測しています)。問題は、以前は機能していた方法に依存するコードがたくさんあることです(ほとんどのコードをES6インポートに変換できますが、すべてをインポートできるわけではありません)。私のプロジェクトを通過してこれを修正する必要なしに、古い方法を動作させる方法に関するヒントを誰かに教えてもらえますか?

ありがとう!

例:

入力:

const foo = {}
export default foo

Babel 5での出力

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;
module.exports = exports["default"];

Babel 6(およびes2015プラグイン)での出力:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;

出力の唯一の違いがであることに注意してくださいmodule.exports = exports["default"]


編集する

私の特定の問題を解決した後に私が書いたこのブログ投稿に興味があるかもしれません:ES6モジュールの誤解、Babel、涙、およびソリューションのアップグレード


私は好奇心旺盛ですが、requireBabelを使用するコードベースで作業している場合に必要なケースは何ですか?おそらく、とにかくそれを回避できる他のアプローチがあります。
loganfsmyth 2015年

:私はそれはのようなデッドコードで見つかった場合は、コードを必要としませんのWebPACKの機能を活用していますif (false) { require('./foo') }WebPACKを含む実際にスキップうとfoo.js結果のバンドルにします。
kentcdodds 2015年

何があなたのfalseトグルになりますか?それがあなたのwebpack設定で利用可能な条件である場合、別のオプションがあるかもしれません。
loganfsmyth 2015年

これも私をかみました。@kentcdoddsに感謝します。
タイラーマクギニス

1
これにより、この投稿が見つかるまでに数時間問題が発生しました。私は自分のすべてを交換することになったexport default {foo, bar}module.exports = {foo, bar}。現在サポートされていない間違ったメソッドがとても気に入りました。
2016年

回答:


90

このプラグインを使用して、古いexport動作を取り戻すこともできます。


1
私は誰かが遅かれ早かれプラグインを書くことを知っていました。ありがとう!
kentcdodds 2015年

残念なことに、babel-plugin-add-module-exportsはamdスタイルのモジュールを(まだ)サポートしていません
zowers

3
私はbabel-plugin-transform-es2015-modules-simple-amdを使用して、AMDモジュールを含むプロジェクトで同じ問題を解決しました
Tom Wayson

UMDとこのプラグインを使用する方法だと思います!ありがとう
electronix384128

とてもとても役に立ちました。
Jovica Aleksic、2018年

105

CommonJSエクスポート動作が必要な場合は、CommonJSを直接使用する必要があります(または他の回答でプラグインを使用する必要があります)。この動作は混乱を招き、無効なES6セマンティクスにつながるため、削除されました。

export default {
  a: 'foo'
};

その後

import {a} from './foo';

これは無効なES6ですが、説明しているCommonJSの相互運用性の動作のために機能しました。残念ながら、両方のケースをサポートすることは不可能であり、人々に無効なES6を書くことを許可することは、あなたがそうすることよりも悪い問題です.default

もう1つの問題は、ユーザーが名前付きエクスポートを将来追加した場合、ユーザーにとって予期しないことでした。たとえば、

export default 4;

その後

require('./mod');
// 4

だが

export default 4;
export var foo = 5;

その後

require('./mod')
// {'default': 4, foo: 5}

以前の動作が正しくなかったことに同意します(そして注記しました)が、私の質問は問題を回避する方法でした。私は正しくない振る舞いに大きく依存していました(今朝まで正しくないことに気づきませんでした)。私はすべてを一度に更新する必要がないことを
望み

現在の動作を取得するための唯一の修正は、CommonJSを直接使用するようにコードを切り替えるか、更新する時間があるまでBabel 5に留まることです。
loganfsmyth 2015年

4
@kentcdoddsこれを機能させるためのwebpackローダー(またはbabelプラグイン)を作成できます。彼らが提供していないことに驚いています(または変更をより大きく宣伝しています!)
Jamund Ferguson

私はこれで混乱しています... export default function () {}モジュールAでimport a from 'a'、モジュールBで実行すると、Babel 6 a{ default: function () {} }... exploringjs.com/es6/から理解できることからこれは機能し、エクスポートを取得する必要がありますオブジェクトではなくBの関数。
mamapitufo 2016年

@mamapitufoそれはうまくいくはずですが、例を見なければ何が悪いのかを言うのは難しいです。チャットしたい場合は、SlackのBabelのサポートチャネルに気軽に立ち寄ってください。
loganfsmyth

33

ライブラリの作成者は、この問題を回避できる場合があります。

通常、エントリポイントindex.jsがあります。これは、のメインフィールドからポイントするファイルですpackage.json。libの実際のエントリポイントを再エクスポートする以外に何もしません。

export { default } from "./components/MyComponent";

バベルの問題を回避するには、これをimportステートメントに変更してから、デフォルトをに割り当てますmodule.exports

import MyComponent from "./components/MyComponent";
module.exports = MyComponent;

他のすべてのファイルは、回避策なしで純粋なES6モジュールのままです。したがって、エントリポイントのみを少し変更する必要があります:)

これはcommonjsが必要とする場合、およびES6インポートの場合にも機能します。これは、Babelが逆の相互運用を削除していないように見えるためです(commonjs-> es6)。Babelはcommonjsにパッチを適用するために次の関数を挿入します。

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

私はこれとの戦いに何時間も費やしてきたので、これが誰か他の人の努力を救うことを願っています!


何らかの理由で、私は私の頭を約右紡糸やったことがなかったmodule.exportsexport defaultもの。今、私たちはスクエアワンに戻っていますか?
windmaomao

@windmaomaoどういう意味ですか?これはトリックなので、commonjsユーザーは必要ありませんrequire("whatever").default。ライブラリの作成者でない場合、これはおそらく無関係です
WickyNilliams

1

私はそのような問題を抱えていました。そしてこれが私の解決策です:

//src/arithmetic.js

export var operations = {
  add: function (a, b) {
      return a + b;
  },

  subtract: function (a, b) {
      return a - b;
  }
};

//src/main.js

import { operations }  from './arithmetic';

let result = operations.add(1, 1);

console.log(result);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.