Tengo funciones IIFE para algunos de los códigos de la biblioteca en una aplicación heredada que necesita funcionar para IE10 + (sin carga del módulo ES6, etc.).
Sin embargo, estoy empezando a desarrollar una aplicación React que usará ES6 y TypeScript y quiero reutilizar el código que ya tengo sin duplicar los archivos. Después de un poco de investigación, descubrí que me gustaría usar un patrón UMD para permitir que estos archivos de biblioteca funcionen como <script src=*>
importaciones y para permitir que la aplicación React los importe a través de la carga del módulo ES6.
Se me ocurrió la siguiente conversión:
var Utils = (function(){
var self = {
MyFunction: function(){
console.log("MyFunction");
}
};
return self;
})();
a
(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");
};
})));
Esto permitirá cargar mediante un Import Utils from './Utils.js'
comando y también permitirá que se inserte usando una etiqueta de script<script src='Utils.js'></script>
Sin embargo, algunos de mis IIFE usan otros IIFE como dependencia (malo, lo sé, pero una realidad).
var Utils = Utils; // Used to indicate that there is dependency on Utils
var RandomHelper = (function(){
var self = {
DoThing: function(){
Utils.MyFunction();
}
};
return self;
})();
Si gire correctamente RandomHelper
y Utils
en archivos que se pueden importar, el Reaccionar aplicación no es compatible con esta técnica. Haciendo simplemente
Import Utils from './Utils.js'
Import RandomHelper from './RandomHelper.js'
no funciona porque creo que Utils no tiene un alcance de ventana. Se cargará sin problemas pero RandomHelper.DoThing()
arrojará que Utils no está definido.
En la aplicación heredada
<script src='Utils.js'></script>
<script src='RandomHelper.js'></script>
funciona perfectamente.
¿Cómo puedo hacer que RandomHelper pueda usar Utils en una aplicación React, manteniéndolo compatible con IE y ES5 pero aún así trabajando en react? ¿Quizás de alguna manera establecer una ventana / variable global?
PD: Entiendo que el objetivo de la carga del módulo ES6 es tratar las dependencias y mis IIFE existentes no son ideales. Planeo cambiar eventualmente las clases de es6 y un mejor control de dependencia, pero por ahora quiero usar lo que está disponible sin tener que volver a escribir
fuente
Respuestas:
Vamos a aclarar esto primero, las funciones del módulo, si no se exportan explícitamente, tienen un ámbito privado para el módulo de definición . No puedes evitar este hecho. Pero hay opciones alternativas que puede considerar.
1. Asumir una modificación mínima del código heredado es aceptable
Una solución alternativa con cambios mínimos en su código heredado sería simplemente agregar
Utils
yRandomHelper
alwindow
objeto. Por ejemplo, cambievar Utils = (...)();
awindow.Utils = (...)();
. En consecuencia, se podrá acceder al objeto desde el objeto global mediante códigos heredados (cargados medianteimport
) y una base de código más reciente.2. Asumiendo que no se puede tolerar absolutamente ninguna modificación en el código heredado
Se debe crear un nuevo módulo ES6 como proxy para cargar los scripts heredados:
Por último, es posible importar
Utils
yRandomHelper
desdelegacy-main.js
cuando sea necesario:fuente
Un enfoque que podría considerar es alguna forma de inyección de dependencia : haga que su aplicación React reciba RandomHelper, o algunas de sus propiedades, del mundo exterior. Luego puede quitarlo cuando esté listo para cortar el cordón.
fuente