#angular #server-side-rendering #angular-universal #prerender
#angular #рендеринг на стороне сервера #angular-универсальный #предварительный рендеринг
Вопрос:
Я ищу способ предоставления токенов со стороны сервера при предварительной визуализации приложения с использованием сценария предварительной визуализации.
Проблема, с которой я сталкиваюсь, связана с этой проблемой
Предоставление токенов для приложения не работает. Я даю значения в виде пустых строк, поскольку поставщики ожидают строки, которые являются: ( req.headers['user-agent']
и a string URL of the request
)
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/web/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? 'index.original.html'
: 'index';
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine(
'html',
ngExpressEngine({
bootstrap: AppServerModule,
providers: [
{
provide: UNIVERSAL_USER_AGENT,
useValue: '',
},
{
provide: UNIVERSAL_LOCATION,
useValue: '',
},
],
})
);
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get(
'*.*',
express.static(distFolder, {
maxAge: '1y',
})
);
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, {
req,
providers: [
{ provide: APP_BASE_HREF, useValue: req.baseUrl },
provideLocation(req),
provideUserAgent(req),
],
});
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
Я также предоставил токены в серверном модуле, но, тем не менее, он их не распознает.
@NgModule({
imports: [AppModule, ServerModule, UniversalModule, FlexLayoutServerModule],
bootstrap: [AppComponent],
providers: [
{
provide: UNIVERSAL_USER_AGENT,
useValue: '',
},
{
provide: UNIVERSAL_LOCATION,
useValue: '',
},
],
})
export class AppServerModule {}
Есть ли способ добиться этого? Я все еще смущен внедрением зависимостей.
Обычный SSR работает, потому что я могу предоставлять токены с использованием фабрик, поскольку они зависят от объекта req.
Но с претендентом у меня нет объекта req, поэтому я не могу использовать фабрики.
Буду признателен за любые предложения и идеи
Ответ №1:
Я использовал Scully, приложение предварительно рендерится, моя проблема решена.
Чтобы начать работу со Скалли, вы можете проверить эту ссылку.
Я заставил его работать, чтобы установить Scully с помощью Angular CLI. add
Схема внесет некоторые изменения в ваш проект для базовой конфигурации, я думаю, что она также добавляет сценарии, которые я отметил ниже.
ng add @scullyio/init
Затем я добавил скрипты в свой package.json
файл, как показано ниже
"scully": "npx scully --",
"scully:serve": "npx scully serve --"
После установки Scully мне просто нужно было создать свое приложение, используя сценарий сборки Angular: ng build
и npm run scully
. Это предварительно обработало мое приложение без каких-либо проблем.
Было ограничение, с которым я столкнулся для динамических маршрутов, когда у меня была конфигурация маршрута Angular, подобная /some-path/232
и 232
динамическая и неизвестная во время сборки, я обошел это ограничение, изменив этот путь маршрута на /some-path
и используя queryParams
для передачи данных, которые мне были нужны для маршрута / компонента. Я надеюсь, что это поможет.
Комментарии:
1. Был бы рад, если бы вы могли поделиться своим решением со Скалли
2. @HariHaran Я обновил ответ