J'ai des fonctions IIFE pour une partie du code de bibliothèque dans une application héritée qui doit fonctionner pour IE10 + (pas de chargement de module ES6, etc.).
Cependant, je commence à développer une application React qui utilisera ES6 et TypeScript et je veux réutiliser le code que j'ai déjà sans dupliquer les fichiers. Après un peu de recherche, j'ai découvert que je souhaitais utiliser un modèle UMD pour permettre à ces fichiers de bibliothèque de fonctionner à la fois en tant <script src=*>
qu'importations et pour permettre à l'application React de les importer via le chargement du module ES6.
J'ai trouvé la conversion suivante:
var Utils = (function(){
var self = {
MyFunction: function(){
console.log("MyFunction");
}
};
return self;
})();
à
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Utils = {})));
}(this, (function (exports) {
exports.MyFunction = function(){
console.log("MyFunction");
};
})));
Cela permettra le chargement via la Import Utils from './Utils.js'
commande et permettra également son insertion à l'aide d'une balise de script<script src='Utils.js'></script>
Cependant, certains de mes IIFE utilisent d'autres IIFE comme dépendance (mauvais je sais mais une réalité).
var Utils = Utils; // Used to indicate that there is dependency on Utils
var RandomHelper = (function(){
var self = {
DoThing: function(){
Utils.MyFunction();
}
};
return self;
})();
Si vous tournez correctement RandomHelper
etUtils
dans des fichiers qui peuvent être importés, REACT application n'est pas compatible avec cette technique. Faire simplement
Import Utils from './Utils.js'
Import RandomHelper from './RandomHelper.js'
ne fonctionne pas parce que je crois que Utils n'est pas à portée de fenêtre. Il se chargera sans problème maisRandomHelper.DoThing()
jettera que Utils n'est pas défini.
Dans l'application héritée
<script src='Utils.js'></script>
<script src='RandomHelper.js'></script>
fonctionne parfaitement.
Comment puis-je faire en sorte que RandomHelper puisse utiliser Utils dans une application React, en la gardant compatible avec IE et ES5 tout en fonctionnant avec React. Peut-être en quelque sorte définir une fenêtre / variable globale?
PS: Je comprends que le but du chargement du module ES6 est de gérer les dépendances et mes IIFE existants ne sont pas idéaux. Je prévois éventuellement de changer de classe es6 et un meilleur contrôle des dépendances, mais pour l'instant, je veux utiliser ce qui est disponible sans être réécrit
Réponses:
Commençons par éliminer les fonctionnalités du module, si elles ne sont pas explicitement exportées, sont étendues en privé au module de définition . Vous ne pouvez pas contourner ce fait. Mais vous pouvez envisager des solutions de contournement.
1. En supposant qu'une modification minimale du code hérité est acceptable
Une solution de contournement avec des modifications minimes à votre code hérité consisterait simplement à ajouter
Utils
etRandomHelper
à l'window
objet. Par exemple, changezvar Utils = (...)();
pourwindow.Utils = (...)();
. Par conséquent, l'objet sera accessible à partir de l'objet global à la fois par les codes hérités (chargés viaimport
) et la base de code plus récente.2. En supposant qu’aucune modification du code hérité ne peut être tolérée
Un nouveau module ES6 doit être créé en tant que proxy pour charger les scripts hérités:
Enfin, vous pouvez importer
Utils
et àRandomHelper
partir enlegacy-main.js
cas de besoin:la source
Une approche que vous pourriez envisager est une forme d' injection de dépendance : demandez à votre application React de recevoir RandomHelper, ou certaines de ses propriétés, du monde extérieur. Ensuite, vous pouvez le retirer lorsque vous êtes prêt à couper le cordon.
la source