Ich habe eine SPA (in Aurelia/TypeScript, aber das sollte nicht wichtig sein), die SystemJS verwendet. Nehmen wir an, es läuft unter http://spa:5000/app
.JavaScript Intercept Modul Import
Es lädt manchmal JavaScript-Module wie waterservice/external.js
auf Anfrage von einer externen URL wie http://otherhost:5002/fetchmodule?moduleId=waterservice.external.js
. Ich benutze SystemJS.import(url)
, um dies zu tun, und es funktioniert gut.
Aber wenn dieses externe Modul ein anderes Modul mit einem einfachen import { OtherClass } from './other-class';
importieren will, funktioniert dies (verständlich) nicht. Wenn es vom SPA geladen wird, sieht es http://spa:5000/app/other-class.js
. In diesem Fall muss ich den Pfad/Standort abfangen, um ihn an http://otherhost:5002/fetchmodule?moduleId=other-class.js
umzuleiten.
Hinweis: Die Typoskript-Kompilierung für waterservice/external.ts
funktioniert, weil der Typskript-Compiler problemlos ./other-class.ts
finden kann. Natürlich kann ich keine absolute URL für den Import verwenden.
Wie kann ich das Laden des Moduls innerhalb eines Moduls abfangen, das ich mit SystemJS importiere?
Ein Ansatz, den ich bereits getestet habe, ist das Hinzufügen einer Zuordnung in der SystemJS-Konfiguration. Wenn ich es wie import { OtherClass } from 'other-class';
importieren und eine Zuordnung wie "other-class": "http://otherhost:5002/fetchmodule?moduleId=other-class"
hinzufügen, funktioniert es. Aber wenn dieser Ansatz gut ist, wie kann ich Mapping dynamisch zur Laufzeit hinzufügen?
Andere Ansätze wie eine generische Lade-URL-Interception sind ebenfalls willkommen.
aktualisieren
Ich versuchte SystemJS abfangen als vorschlagen, durch artem wie diese
var systemLoader = SystemJS;
var defaultNormalize = systemLoader.normalize;
systemLoader.normalize = function(name, parentName) {
console.error("Intercepting", name, parentName);
return defaultNormalize(name, parentName);
}
Dies würde normalerweise nichts ändern, aber einige Konsolenausgabe produzieren, um zu sehen, was los ist auf. Leider scheint dies etwas zu ändern, da ich einen Fehler bekomme. Uncaught (in Versprechung) TypeError: this.has ist keine Funktion innerhalb system.js
.
Dann habe ich versucht, Zuordnungen mit SystemJS.config({map: ...});
hinzuzufügen. Überraschenderweise arbeitet diese Funktion inkrementell, wenn ich sie anrufe, verliert sie nicht die bereits bereitgestellten Mappings. So kann ich tun:
System.config({map: {
"other-class": `http://otherhost:5002/fetchModule?moduleId=other-class.js`
}});
Dies funktioniert nicht mit relativen Pfaden (jene, die mit .
oder ..
beginnen), aber wenn ich die gemeinsam denjenigen in der Wurzel setzen das funktioniert.
Ich würde immer noch lieber das Laden abfangen, um mit mehr Szenarien umgehen zu können, aber im Moment habe ich keine Ahnung, welche has
Funktion in dem obigen Ansatz fehlt.
Aufgrund eines Feiertages hatte ich keine Zeit, um diesen Vorschlag jetzt zu sehen, aber werde es tun. Verleihung des Kopfgelds, weil es andernfalls ablaufen würde. Ich könnte jedoch mit Fragen zurückkommen;) – ZoolWay
Danke für Ihre Einsicht. Ich habe die Frage mit beiden Versuchen aktualisiert. Haben Sie eine Idee, warum das Abfangen von "normalisieren" in meinem Fall einen Fehler erzeugt? – ZoolWay
Oh mein Fehler tut mir leid - defaultNormalize braucht 'dieses' Argument: defaultNoramlize.call (loader, name, parentName); – artem