У меня есть SPA (на Aurelia / TypeScript, но это не имеет значения), в котором используется SystemJS. Допустим, он работает на http://spa:5000/app
.
Иногда он загружает модули JavaScript, такие как waterservice/external.js
, по запросу с внешнего URL-адреса, например http://otherhost:5002/fetchmodule?moduleId=waterservice.external.js
. Я использую SystemJS.import(url)
для этого, и он отлично работает.
Но когда этот внешний модуль хочет импортировать другой модуль с простым import { OtherClass } from './other-class';
, это (понятно) не работает. При загрузке SPA он смотрит на http://spa:5000/app/other-class.js
. В этом случае мне нужно перехватить путь / местоположение, чтобы перенаправить его на http://otherhost:5002/fetchmodule?moduleId=other-class.js
.
Примечание. Компиляция Typescript для waterservice/external.ts
работает с поиском, потому что компилятор машинописного текста может легко найти ./other-class.ts
. Очевидно, я не могу использовать абсолютный URL-адрес для импорта.
Как я могу перехватить загрузку модуля внутри модуля, который я импортирую с помощью SystemJS?
Один из подходов, который я уже тестировал, - это добавить отображение в конфигурацию SystemJS. Если я импортирую его как import { OtherClass } from 'other-class';
и добавлю сопоставление типа "other-class": "http://otherhost:5002/fetchmodule?moduleId=other-class"
, он работает. Но если этот подход хорош, как я могу добавить отображение динамически во время выполнения?
Также приветствуются другие подходы, такие как перехват универсального URL-адреса загрузки.
Обновить
Я попытался перехватить SystemJS, как предлагает artem вот так
var systemLoader = SystemJS;
var defaultNormalize = systemLoader.normalize;
systemLoader.normalize = function(name, parentName) {
console.error("Intercepting", name, parentName);
return defaultNormalize(name, parentName);
}
Обычно это ничего не меняет, но производит некоторый консольный вывод, чтобы увидеть, что происходит. К сожалению, это, похоже, что-то меняет, поскольку я получаю сообщение об ошибке Uncaught (в обещании) TypeError: this.has не является функцией внутри system.js
.
Затем я попытался добавить сопоставления с SystemJS.config({map: ...});
. Удивительно, но эта функция работает инкрементально, поэтому, когда я ее вызываю, она не теряет уже предоставленные сопоставления. Итак, я могу:
System.config({map: {
"other-class": `http://otherhost:5002/fetchModule?moduleId=other-class.js`
}});
Это не работает с относительными путями (те, которые начинаются с .
или ..
), но если я помещу общие в корень, это сработает.
Я бы по-прежнему предпочел перехватить загрузку, чтобы иметь возможность обрабатывать больше сценариев, но на данный момент я понятия не имею, какая функция has
отсутствует в приведенном выше подходе.