@angular/ssr/node not working as intended
- Linguagem predominante
- TypeScript
- Estrelas
- 7.8k
- Forks
- 2.2k
- Merge médio
- 22h 28min
- PRs com merge (30d)
- 6
Descrição
I am using @angular/fire@19.0.0-rc.4, and I have the following:
`src/server.ts`
>import {
> AngularNodeAppEngine,
> createNodeRequestHandler,
> isMainModule,
> writeResponseToNodeResponse,
>} from "@angular/ssr/node";
>
>import express from "express";
>
>import { dirname, resolve } from "node:path";
>import { fileURLToPath } from "node:url";
>
>const serverDistFolder = dirname(fileURLToPath(import.meta.url));
>const browserDistFolder = resolve(serverDistFolder, "../browser");
>
>const server = express();
>const angularNodeAppEngine = new AngularNodeAppEngine();
>
>server.use(
> express.static(browserDistFolder, {
> maxAge: "1y",
> index: false,
> redirect: false,
> }),
>);
>
>server.use("/**", (serverRequest, serverResponse, serverNextFunction) => {
> angularNodeAppEngine
> .handle(serverRequest)
> .then((response) => {
> if (response) {
> return writeResponseToNodeResponse(response, serverResponse);
> } else {
> return serverNextFunction();
> }
> })
> .catch(serverNextFunction);
>});
>
>if (isMainModule(import.meta.url)) {
> const port = process.env["PORT"] || 4000;
> server.listen(port, () => {
> console.log(``Node Express server listening on http://localhost:${port}``);
> });
>}
>
>export const reqHandler = createNodeRequestHandler(server);
`src/app/app.routes.ts`
>import { Route } from "@angular/router";
>
>import { ErrorComponent } from "./error/error.component";
>import { errorResolver } from "./error/error.resolver";
>import { HomeComponent } from "./home/home.component";
>import { homeResolver } from "./home/home.resolver";
>
>export const routes: Route[] = [
> {
> path: "error",
> component: ErrorComponent,
> resolve: {
> error: errorResolver,
> },
> },
> {
> path: "",
> pathMatch: "full",
> component: HomeComponent,
> resolve: {
> home: homeResolver,
> },
> },
> {
> path: "**",
> redirectTo: "/error",
> },
>];
`src/app/app.routes.server.ts`
>import { RenderMode, ServerRoute } from "@angular/ssr";
>
>export const serverRoutes: ServerRoute[] = [
> {
> path: "**",
> renderMode: RenderMode.Server,
> },
>];
`src/app/app.config.ts`
>import {
> ApplicationConfig,
> provideExperimentalZonelessChangeDetection,
>} from "@angular/core";
>import { initializeApp, provideFirebaseApp } from "@angular/fire/app";
>import { getAnalytics, provideAnalytics } from "@angular/fire/analytics";
>import { getFirestore, provideFirestore } from "@angular/fire/firestore";
>import { getStorage, provideStorage } from "@angular/fire/storage";
>import {
> provideClientHydration,
> withEventReplay,
>} from "@angular/platform-browser";
>import {
> provideRouter,
> withEnabledBlockingInitialNavigation,
> withInMemoryScrolling,
>} from "@angular/router";
>
>import { routes } from "./app.routes";
>
>import { environment } from "../environments/environment.production";
>
>export const appConfig: ApplicationConfig = {
> providers: [
> provideExperimentalZonelessChangeDetection(),
> provideClientHydration(withEventReplay()),
> provideRouter(
> routes,
> withEnabledBlockingInitialNavigation(),
> withInMemoryScrolling({
> anchorScrolling: "enabled",
> scrollPositionRestoration: "enabled",
> }),
> ),
> provideFirebaseApp(() => {
> return initializeApp(environment.firebase);
> }),
> provideAnalytics(() => {
> return getAnalytics();
> }),
> provideFirestore(() => {
> return getFirestore();
> }),
> provideStorage(() => {
> return getStorage();
> }),
> ],
>};
`src/app/app.config.server.ts`
>import { mergeApplicationConfig, ApplicationConfig } from "@angular/core";
>import { provideServerRendering } from "@angular/platform-server";
>import { provideServerRoutesConfig } from "@angular/ssr";
>
>import { appConfig } from "./app.config";
>import { serverRoutes } from "./app.routes.server";
>
>const serverConfig: ApplicationConfig = {
> providers: [
> provideServerRendering(),
> provideServerRoutesConfig(serverRoutes),
> ],
>};
>
>export const config = mergeApplicationConfig(appConfig, serverConfig);
Now, I am not using `ng deploy` or `firebase deploy` since they require `@angular-devkit/build-angular` and the SSR function being deployed is not working. Instead, I created a separate Firebase Repo and initialised both hosting and functions.
`firebase.json`
>{
> "functions": [
> {
> "source": "functions/ssr",
> "codebase": "ssr",
> "ignore": [...]
> }
> ],
> "hosting": {
> "public": "hosting",
> "ignore": [...],
> "rewrites": [
> {
> "source": "**",
> "function": {
> "functionId": "ssr",
> "region": "europe-west1"
> }
> }
> ]
> }
>}
`functions/ssr/index.js`
>import { onRequest } from "firebase-functions/v2/https";
>
>import { reqHandler } from "./build/template/server/server.mjs";
>
>export const ssr = onRequest(
> {
> region: "europe-west1",
> invoker: "public",
> memory: "256MiB",
> cpu: 1,
> timeoutSeconds: 60,
> concurrency: 80,
> minInstances: 1,
> maxInstances: 100,
> ingressSettings: "ALLOW_ALL",
> preserveExternalChanges: false,
> },
> reqHandler,
>);
In the Firebase Repo, I am successfully deploying both hosting and functions using `firebase deploy`. The SSR function works, save for paths redirected to the ErrorComponent:
`src/app/app.routes.ts`
> {
> path: "**",
> redirectTo: "/error",
> },
When seeing the Google Cloud Console logs for the Cloud function, the express instance is giving a 302 response (which is what you'd expect from a redirect), however, instead of staying on port 80, the redirect URL is given on port 8080, which is the internal port being using by the express instance. I reckon that server.ts needs to be modified, however, I don't know how.
Guia de contribuição
Direção de pesquisa
Comece com src/server.ts e functions/ssr/index.js e, em seguida, compare o redirecionamento da rota /error em src/app/app.routes.ts com a solicitação do Firebase Hosting implantado. Inspecione a resposta 302 Location da Cloud Function e verifique se o comportamento concluído preserva a URL pública do Hosting em vez de expor a porta 8080.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- angular, express, firebase, node.js, typescript
- Domínio
- backend, cloud, web-dev
- Tipo de issue
- Bug
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Status de atividade
- Estagnada
- Clareza
- Razoavelmente clara
- Facilidade para iniciantes
- 38/100