web-dev-qa-db-ja.com

ES2015の条件付きエクスポート

ポリフィルを開発していて、クラスがブラウザにすでに存在する場合、そのクラスをシムしたくないとします。 ES6でこれを行うにはどうすればよいですか? exportsはステートメントではないため、以下は無効です。

if (typeof Foo === 'undefined') {
  export class Foo { ... }
}

上記の条件がfalseと評価された場合、インポートスクリプトはブラウザを組み込みで取得する必要があります。

13
Dan Dascalescu

exportは静的でなければなりません。条件付きエクスポートでは、CommonJSモジュールとexportsを使用できます。

ES6モジュールで次のように処理する必要があります。

export let Foo;

if (window.Foo === undefined) {
  Foo = class Foo { ... }
} else {
  Foo = window.Foo;
}

プラットフォームに依存しないソリューションの場合(thisはトランスパイルされたコードのグローバルと等しくない場合があります)window

const root = (() => eval)()('this');
if (root.Foo === undefined) {
...

これは、このように設計されたES6モジュールのバインディング機能を悪用します 循環依存関係を処理するため および大幅に説明 ここ

上記のコード transpiles to

...
var Foo = exports.Foo = void 0;

if (window.Foo === undefined) {
  exports.Foo = Foo = function Foo() {
    _classCallCheck(this, Foo);
  };
} else {
  exports.Foo = Foo = window.Foo;
}

この場合、エクスポートは条件付きではありませんが、このエクスポートにバインドされているFoo値は条件付きです。

10
Estus Flask

export構文は、どのエクスポートが存在するかを宣言するため、モジュールのトップレベルのスコープである必要があります。ただし、条件付きで値を自由に割り当てることもできます。

export let Foo = global.Foo;

if (typeof Foo === 'undefined'){
    Foo = class { ... }
}
10
loganfsmyth

上記の方法は、Webpackではうまく機能しませんでした。条件付きの救済により、Webpackの警告が発生し、縮小前にバンドルサイズが20KB増加しました。

Webpackプラグインには、本番ビルド向けに最適化された最適化機能があります。次のコードは、バンドルサイズを増やすことなく機能しました。

let comp = null;
if (process.env.NODE_ENV) {
  comp = require('./MyDevComp').default;
}

上記の条件付き要求では、本番ビルドのバンドルサイズは増加しませんでした。

0
vijayst