angular / angular/angularfire

@angular/ssr/node not working as intended

Đang mở
#3,596 2 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
TypeScript
Star
7.8k
Fork
2.2k
Merge trung bình
22 giờ 28 phút
Pull request đã merge (30 ngày)
6

Mô tả

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.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với src/server.ts và functions/ssr/index.js, sau đó so sánh chuyển hướng từ route /error trong src/app/app.routes.ts với request Firebase Hosting đã triển khai. Kiểm tra phản hồi 302 Location của Cloud Function và xác minh rằng hành vi hoàn thiện giữ nguyên URL Hosting công khai thay vì để lộ cổng 8080.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
angular, express, firebase, node.js, typescript
Lĩnh vực
backend, cloud, web-dev
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
38/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.