Справочная информация: Использование Angular Universal для выполнения предварительного рендеринга, но не все маршруты будут отображаться (страницы с параметризацией или только для аутентификации по большей части), поэтому требуется откат к express рендер при необходимости.
Быстрая репликация (bash):
npm install -g @angular/cli@next
ng new partial-prerender -s -t --minimal --routing --interactive=false
cd partial-prerender/
ng add @nguniversal/express-engine@'^9.0.0-rc.1'
ng g m child --route child --module app
cat << 'EOF' > src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
template: `<div [routerLink]="['/']">Root</div><div [routerLink]="['child']">Child</div><router-outlet></router-outlet>`,
})
export class AppComponent {}
EOF
npm run prerender
npm run serve:ssr
Эта быстрая репликация создаст приложение, универсальную реализацию, дочернюю страницу и заменит приложение html, чтобы дать 2 ссылки и выход для маршрутизатора, а затем построить / предварительно -render. Оба маршрута будут предварительно обработаны, но этого достаточно для обсуждения проблемы.
Проблема: Dynami c SSR выполняется, поскольку сервер Express принимает запрос вместо того, чтобы обслуживать предварительно обработанный файл stati c. URL-адреса обычно доступны без указания /index.html
.
Обратите внимание, что файлы stati c можно найти в /dist/partial-prerender/browser/index.html
и .../child/index.html
. Для тестирования я заменил содержимое этих файлов мусором, просто чтобы быть уверенным, какая информация загружается с первого взгляда.
Можно также добавить console.log('DYNAMIC');
к server.ts
:
server.get('*', (req, res) => {
console.log('DYNAMIC');
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
При отправке запроса на localhost:4000
или localhost:4000/child
будет напечатано 'DYNAMI C', и будет создана динамически отображаемая версия, не давая мне искаженных предварительно обработанных файлов.
При отправке запроса на localhost:4000/index.html
или localhost:4000/child/index.html
,
server.get('*.*', express.static(distFolder, { maxAge: '1y' }));
берет и обслуживает искалеченные файлы.
Все имеет смысл и почему это происходит, но я хочу чтобы иметь возможность просто нажать на указанный URL-адрес (без /index.html
и получить предварительно отрендеренные файлы (при наличии), а затем вернуться к работе SSR.
Потенциальное решение : Изменить server.ts
, чтобы проверить, существует ли файл, соответствующий заданному пути запроса + /index.html
, и обработать их, возвращаясь к res.render(...
- Это лучший способ?
- Если это так, то почему это не будет функциональностью по умолчанию? Если вы делаете это с обратным прокси-сервером, не добавляя накладные расходы на проверку.
- Какой лучший способ сделать это?
- Не использовался Express интенсивно в течение, возможно, 6 лет, но чувствую, что
express.static
следует использовать каким-то образом в течение fs
- Если
fs
является ответом, будет имеет смысл кэшировать предварительно отрендеренные файлы в память?
Если это поможет, я создаю контейнер с альпийским узлом и развертываюсь на K8 с входом Nginx. Только упомяните это, как будто есть волшебная try-files
-подобная функциональность, которая может быть сделана, чтобы «попытаться» получить файл + /index.html
из контейнера узла, затем выполнить откат без /index.html
, но кажется маловероятным.