ポリフィルを開発していて、クラスがブラウザにすでに存在する場合、そのクラスをシムしたくないとします。 ES6でこれを行うにはどうすればよいですか? exports
はステートメントではないため、以下は無効です。
if (typeof Foo === 'undefined') {
export class Foo { ... }
}
上記の条件がfalse
と評価された場合、インポートスクリプトはブラウザを組み込みで取得する必要があります。
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
値は条件付きです。
export
構文は、どのエクスポートが存在するかを宣言するため、モジュールのトップレベルのスコープである必要があります。ただし、条件付きで値を自由に割り当てることもできます。
export let Foo = global.Foo;
if (typeof Foo === 'undefined'){
Foo = class { ... }
}
上記の方法は、Webpackではうまく機能しませんでした。条件付きの救済により、Webpackの警告が発生し、縮小前にバンドルサイズが20KB増加しました。
Webpackプラグインには、本番ビルド向けに最適化された最適化機能があります。次のコードは、バンドルサイズを増やすことなく機能しました。
let comp = null;
if (process.env.NODE_ENV) {
comp = require('./MyDevComp').default;
}
上記の条件付き要求では、本番ビルドのバンドルサイズは増加しませんでした。