web-dev-qa-db-fra.com

Exportation conditionnelle dans ES2015

Disons que vous développez un polyfill et que vous ne voulez pas modifier une classe si elle existe déjà dans le navigateur. Comment cela peut-il être fait dans ES6? Ce qui suit n'est pas valide car exports n'est pas une déclaration:

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

Si la condition ci-dessus est évaluée à false, le script d'importation doit intégrer le navigateur.

10
Dan Dascalescu

La syntaxe export doit figurer dans la portée de niveau supérieur d'un module car vous déclarez quelles exportations existent. Vous êtes libre de leur attribuer conditionnellement une valeur, comme

export let Foo = global.Foo;

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

export devrait être statique. Pour les exportations conditionnelles, les modules CommonJS et exports peuvent être utilisés.

Il devrait être manipulé avec les modules ES6 de cette façon:

export let Foo;

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

Pour une solution indépendante de la plate-forme (this peut ne pas être égal à global dans le code transpilé) window peut être remplacé par

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

Cela exploite la fonctionnalité de liaison des modules ES6 conçue de cette façon pour gérer les dépendances cycliques et explique beaucoup ici .

Le code ci-dessus transpile en

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

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

Dans ce cas, l'exportation n'est pas conditionnelle, mais la valeur Foo liée à cette exportation est conditionnelle.

6
estus

Les méthodes ci-dessus ne fonctionnaient pas bien pour moi avec Webpack. Le renflouement conditionnel a provoqué des avertissements Webpack qui ont augmenté la taille du paquet de 20 Ko avant la minification.

Les plugins Webpack ont ​​une optimisation qui entre en jeu pour les versions de production. Le code suivant a fonctionné pour moi sans augmenter la taille du paquet.

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

La condition requise ci-dessus n'a pas augmenté la taille de l'ensemble pour les versions de production.

0
vijayst