2016-08-04 31 views
12

Mam SPA (w Aurelia/TypeScript, ale to nie powinno mieć znaczenia), który używa SystemJS. Załóżmy, że działa pod adresem http://spa:5000/app.Importowanie modułu przechwytującego JavaScript

Czasami ładuje moduły JavaScript, takie jak waterservice/external.js na żądanie z zewnętrznego adresu URL, takiego jak http://otherhost:5002/fetchmodule?moduleId=waterservice.external.js. Używam do tego celu SystemJS.import(url) i działa dobrze.

Ale kiedy ten moduł zewnętrzny chce zaimportować inny moduł za pomocą prostego import { OtherClass } from './other-class';, to (zrozumiałe) nie działa. Po załadowaniu przez SPA wygląda na http://spa:5000/app/other-class.js. W tym przypadku muszę przechwycić ścieżkę/lokalizację, aby przekierować ją do http://otherhost:5002/fetchmodule?moduleId=other-class.js.

Uwaga: Kompilacja Maszynopisów dla waterservice/external.ts działa, ponieważ kompilator maszynopisu może łatwo znaleźć ./other-class.ts. Oczywiście nie mogę użyć bezwzględnego adresu URL do importu.

Jak mogę przechwycić ładowanie modułu w module, który importuję za pomocą SystemJS?

Jednym z testowanych już sposobów jest dodanie mapowania w konfiguracji SystemJS. Jeśli zaimportuję go jak import { OtherClass } from 'other-class'; i doda mapowanie, takie jak "other-class": "http://otherhost:5002/fetchmodule?moduleId=other-class", to działa. Ale jeśli to podejście jest dobre, w jaki sposób mogę dynamicznie dodawać mapowanie w środowisku wykonawczym?

Inne podejścia, takie jak ogólne przechwytywanie adresów URL, są również mile widziane.


Aktualizacja

próbowałem przechwycić SystemJS jak sugerują przez artem jak ten

var systemLoader = SystemJS; 
var defaultNormalize = systemLoader.normalize; 
systemLoader.normalize = function(name, parentName) { 
    console.error("Intercepting", name, parentName); 
    return defaultNormalize(name, parentName); 
} 

To normalnie nie zmienia niczego, ale produkować jakieś wyjście konsoli, aby zobaczyć, co się dzieje na. Niestety wydaje się, że coś się zmieniło, ponieważ otrzymuję komunikat o błędzie Uncaught (in promise) TypeError: this.has nie jest funkcją wewnątrz system.js.

Następnie próbowałem dodać mapowania z SystemJS.config({map: ...});. Zaskakująco, ta funkcja działa przyrostowo, więc gdy ją nazywam, nie traci już dostarczonych mapowań. Więc mogę zrobić:

System.config({map: { 
    "other-class": `http://otherhost:5002/fetchModule?moduleId=other-class.js` 
}}); 

ta nie działa z ścieżek względnych (tych, które zaczynają się . lub ..), ale jeśli mogę umieścić te udostępnione w korzeniu to działa.

Wciąż wolałbym przechwytywać ładowanie, aby móc obsłużyć więcej scenariuszy, ale w tej chwili nie mam pojęcia, która funkcja has brakuje w powyższym podejściu.

Odpowiedz

2

how can I add mapping dynamically at runtime?

AFAIK SystemJS mogą być konfigurowane w dowolnym momencie po prostu dzwoniąc

SystemJS.config({ map: { additional-mappings-here ... }}); 

Jeśli to nie zadziała, można zastąpić ładowarki.znormalizuj i dodaj własne mapowanie z identyfikatorów modułów do adresów URL. Coś wzdłuż tych linii:

// assuming you have one global SystemJS instance 
var loader = SystemJS; 

var defaultNormalize = loader.normalize; 
loader.normalize = function(name, parentName) { 
    if (parentName == 'your-external-module' && name == 'your-external-submodule') { 
     return Promise.resolve('your-submodule-url'); 
    } else { 
     return defaultNormalize.call(loader, name, parentName); 
    } 
} 

Nie mam pojęcia, czy to będzie działać z maszynopis, czy nie. Ponadto, będziesz musiał dowiedzieć się, jakie dokładnie nazwy są przekazywane do loader.normalize w twoim przypadku.

Ponadto, jeśli używasz konstruktora systemjs do pakowania kodu, będziesz musiał dodać to przesłonięcie do modułu ładującego używanego przez program budujący (i to jest cała inna historia).

+0

Z powodu święta nie miałem teraz czasu, aby przyjrzeć się tej sugestii, ale zrobię to. Przyznanie nagrody, ponieważ inaczej wygasłoby. Mogę jednak wrócić z pytaniami;) – ZoolWay

+0

Dzięki za twój wgląd. Zaktualizowałem pytanie za pomocą obu prób. Czy masz pomysł, dlaczego przechwycenie 'normalize' powoduje błąd w moim przypadku? – ZoolWay

+0

O, przepraszam, mój błąd - defaultNormalize potrzeby 'this' argument: defaultNoramlize.call (loader, name, parentName); – artem

Powiązane problemy