Angular Universal - несколько экземпляров скрипта, внедренного TransferState (<script id="myapp-state"> ... </script>)
У меня есть приложение Angular 7 с реализованным Angular Universal. Это довольно большое приложение с несколькими ленивыми модулями. Я используюTransferState
модуль, и все идет хорошо, ээээ, за исключением того, что на некоторых страницах скрипт вводитсяTransferState
модуль "двойной". Есть как минимум два случая, например:
<script id="myapp-state">{ objectA }</script>
<script id="myapp-state">{ objectB }</script>
И что еще хуже, содержание внутри обоих разное. Поэтому, когда клиентское приложение загружается, иногда оно пытается получить данные, которые хранятся в objectB, но не может найти их в objectA, который проверяется, потому что... он первый? (Это внутренняя логикаTransferState
модуль, я полагаю).
У меня нет особых надежд на ответ, поскольку я не могу предоставить слишком много документации, но, возможно, кто-то столкнулся с подобной проблемой.
Что может быть причиной? Какая частьTransferState
модуль отвечает за внедрение этого скрипта, и почему он не выдает ошибку, если она уже есть?
Обновить:
Вот main.browser.ts
файл:
if (environment.production) {
enableProdMode();
}
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic()
.bootstrapModule(BrowserAppModule)
.catch(err => console.error(err));
});
и вот main.server.ts
файл:
if (environment.production) {
enableProdMode();
}
export { ServerAppModule } from './app/server.app.module';
Мой server.app.module.ts
:
@NgModule({
bootstrap: [
AppComponent
],
imports: [
AppModule,
ServerModule,
BrowserModule.withServerTransition({
appId: APPLICATION_NAME
}),
NoopAnimationsModule,
ModuleMapLoaderModule,
ServerTransferStateModule
]
})
export class ServerAppModule {
}
и мой browser.app.module
:
@NgModule({
bootstrap: [
AppComponent
],
imports: [
BrowserModule.withServerTransition({
appId: APPLICATION_NAME
}),
BrowserAnimationsModule,
BrowserTransferStateModule,
AppModule
]
})
export class BrowserAppModule {
}
И моторная часть моей server.ts
:
app.engine('html', (filePath, options, callback) => {
const engine = ngExpressEngine({
bootstrap: ServerAppModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP),
{ provide: REQUEST, useFactory: () => (options as any).req, deps: [] },
{ provide: RESPONSE, useFactory: () => (options as any).req.res, deps: [] },
{ provide: LOCALES, useFactory: () => allLocalizationStrings, deps: [] },
]
});
engine(filePath, options as any, callback);
});
ОБНОВЛЕНИЕ: похоже, это связано с моим предварительным рендерингом. Если деактивировать, все работает правильно. Если я активирую его, он не будет работать правильно, независимо от маршрута, который я рендерю. Вот как я сейчас выполняю предварительный рендеринг:
const html = await renderModuleFactory(ServerAppModuleNgFactory, {
document: baseIndex,
url: route,
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP),
{ provide: IS_PRE_RENDER, useFactory: () => true, deps: [] },
{ provide: ERROR_WRAPPER, useValue: (errorWrapper) }
]
});