есть два разных модуля: один для десктопа, другой для мобилки.
Бэкэнд выдает страничку, где инлайново в window выписан объект, содержащий в себе, помимо прочего, переменную layout.
Если переменная в layout === “mobile”, то мне нужно грузить модуль mobile, если нет - desktop.
Грузить модули нужно через lazyloading.
В роутах можно было бы прописать loadChildren: path_to_module. Но в моем случае это не прокатывает, потому что оба модуля должны грузиться в root path (path: “”). Если использовать loadChildren - возникнет конфликт. Получается, я должен грузить модуль с динамическим путем на один роут. Что-то типа
{
path: “”,
loadChildren: output === “mobile” ? path_to_mobile : path_to_desktop
}
Это работает, в принципе. Но не работает с AOT. Я попробовал использовать ручную загрузку модулей в обход обычного роутера. Для того, чтобы грузить действительно динамические модули, я заюзал moduleFactory (выполняется на ngOnInit в рутовом компоненте)
this.loader.load("./ca/" + output + "/ca.module." + output + "#CaModule")
.then((moduleFactory: NgModuleFactory<any>) => {
const entryComponent = (moduleFactory.moduleType as any).entry;
const moduleRef = moduleFactory.create(this.inj);
const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.container.createComponent(compFactory);
});
И это действительно грузит нужный мне модуль. Но.
Внутри каждого из этих двух модулей есть свои роуты. RouterModule.forRoot(routes).
И вот эти роуты не инициализируются.
Есть ли у вас опыт, как правильно импортировать модули с динамическим путем, да так, чтобы это еще с АОТ работало? Может накинете какую-нибудь идею, как это решить
ну наверно потому - что "forRoot" регистрируется 1 раз на все апп, а в лейзи модулях надо форЧаилд использовать
Ребят, у меня вновь вопрос о лейзи-лоадинге. Я задавал похожий неделю назад (ссылка чуть выше). Если кто что знает - буду очень благодарен за помощь или наводку. У меня есть приложение, в котором есть два модуля. Один должен грузиться для Desktop, другой для Mobile версии. В приложении есть рут-модуль, который анализирует объект window и находит в нем объект, какой модуль грузить. Оба модуля достаточно независимы и содержат достаточно много разной логики, поэтому грузить их вместе не имеет смысла. Правильнее использовать Lazy Loading. Все работает хорошо, если модули на разных роутах. Например, рутовый модуль получает задание “грузи мобильный модуль” и редиректит на /mobile/…. Модуль через loadChildren грузится лениво. То же самое с десктопом. Можно пойти дальше и загрузить модуль с помощью moduleFactory в рутовом компоненте. this.loader.load("./ca/" + this.layout + "/ca.module#CaModule") .then((moduleFactory: NgModuleFactory<any>) => { const entryComponent = (moduleFactory.moduleType as any).entry; const moduleRef = moduleFactory.create(this.inj); const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent); const compRef = this.container.createComponent(compFactory); }); И это тоже работает. Необходимый модуль лениво загружается даже в том случае, если он на корневом роуте. И все ломается, когда я включаю AOT. В случае AOT, если я имею два модуля на одном пути роута, они грузятся оба. А лоадер внутри компонента инициализирует только нужный модуль. Мне же нужно, чтобы грузился и инициализировался только один модуль. Для этого я пробовал в loadChildren использовать promise System.import("../" + output + "/ca.module").then((mod) => resolve(mod.CaModule));. Но тогда приложение в консоль ругается, что compiler have not been provided. То есть для использования этого пути, придется в АОТ бандл проносить JIT-компилятор. А с ним особого смысла в AOT тогда и нет.
Обсуждают сегодня