Ich habe IIFE- Funktionen für einen Teil des Bibliothekscodes in einer Legacy-Anwendung, die für IE10 + funktionieren muss (kein Laden des ES6-Moduls usw.).
Ich beginne jedoch mit der Entwicklung einer React-App, die ES6 und TypeScript verwendet, und möchte den bereits vorhandenen Code wiederverwenden, ohne die Dateien zu duplizieren. Nach einigen Recherchen stellte ich fest, dass ich ein UMD-Muster verwenden möchte, damit diese Bibliotheksdateien sowohl als <script src=*>
Importe als auch von der React-App über das Laden des ES6-Moduls importiert werden können.
Ich habe mir folgende Konvertierung ausgedacht:
var Utils = (function(){
var self = {
MyFunction: function(){
console.log("MyFunction");
}
};
return self;
})();
zu
(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");
};
})));
Dies ermöglicht das Laden über einen Import Utils from './Utils.js'
Befehl und das Einfügen mithilfe eines Skript-Tags<script src='Utils.js'></script>
Einige meiner IIFE verwenden jedoch andere IIFE als Abhängigkeit (schlecht, ich weiß, aber eine Realität).
var Utils = Utils; // Used to indicate that there is dependency on Utils
var RandomHelper = (function(){
var self = {
DoThing: function(){
Utils.MyFunction();
}
};
return self;
})();
Wenn es richtig drehen RandomHelper
und Utils
in Dateien , die importiert werden können, reagieren die App mit dieser Technik nicht kompatibel sind. Einfach machen
Import Utils from './Utils.js'
Import RandomHelper from './RandomHelper.js'
funktioniert nicht, weil ich glaube, dass Utils keinen Fensterbereich hat. Es wird ohne RandomHelper.DoThing()
Probleme geladen, aber es wird ausgelöst, dass Utils nicht definiert ist.
In der Legacy-App
<script src='Utils.js'></script>
<script src='RandomHelper.js'></script>
funktioniert einwandfrei.
Wie kann ich RandomHelper dazu bringen, Utils in einer React-App zu verwenden, damit IE- und ES5-kompatibel bleiben und trotzdem reagieren können? Vielleicht irgendwie ein Fenster / eine globale Variable setzen?
PS: Ich verstehe, dass der Sinn des Ladens des ES6-Moduls darin besteht, mit Abhängigkeiten umzugehen, und meine vorhandenen IIFEs sind nicht ideal. Ich habe vor, irgendwann die es6-Klassen und eine bessere Abhängigkeitskontrolle zu wechseln, aber jetzt möchte ich das verwenden, was verfügbar ist, ohne es neu zu schreiben
quelle
Antworten:
Lassen Sie uns dies zunächst aus dem Weg räumen. Wenn Modulfunktionen nicht explizit exportiert werden, werden sie privat auf das definierende Modul übertragen . Sie können diese Tatsache nicht umgehen. Es gibt jedoch Umgehungsoptionen, die Sie in Betracht ziehen können.
1. Angenommen, eine minimale Änderung des Legacy-Codes ist akzeptabel
Eine Lösung mit minimalen Änderungen an Ihrem Legacy-Code besteht darin , das Objekt einfach hinzuzufügen
Utils
undRandomHelper
zu ergänzenwindow
. Wechseln Sie beispielsweisevar Utils = (...)();
zuwindow.Utils = (...)();
. Folglich kann sowohl über Legacy-Codes (geladen überimport
) als auch über eine neuere Codebasis vom globalen Objekt aus auf das Objekt zugegriffen werden.2. Es wird davon ausgegangen, dass absolut keine Änderungen am Legacy-Code toleriert werden können
Ein neues ES6-Modul sollte als Proxy zum Laden der Legacy-Skripte erstellt werden:
Schließlich können Sie importieren
Utils
undRandomHelper
auslegacy-main.js
bei Bedarf:quelle
Ein Ansatz, den Sie in Betracht ziehen könnten, ist eine Form der Abhängigkeitsinjektion : Lassen Sie Ihre React-App RandomHelper oder einige seiner Eigenschaften von der Außenwelt erhalten. Dann können Sie es entfernen, wenn Sie bereit sind, das Kabel abzuschneiden.
quelle