整合 Angular Universal

透過 Firebase 架構感知 CLI,您可以將 Angular 應用程式部署至 Firebase,並為使用者提供動態內容。

事前準備

開始將應用程式部署至 Firebase 前,請先詳閱下列規定和選項:

  • Firebase CLI 12.1.0 以上版本。請務必使用偏好的方法安裝 CLI
  • 選用:在 Firebase 專案中啟用付費功能 (如要使用 SSR,則為必要條件)

  • 選用:AngularFire

初始化 Firebase

如要開始使用,請為架構專案初始化 Firebase。請為新專案使用 Firebase CLI,或為現有專案修改 firebase.json

初始化新專案

  1. Firebase CLI 中啟用網頁架構預覽功能:
    firebase experiments:enable webframeworks
  2. 請透過 CLI 執行初始化指令,然後按照提示操作:

    firebase init hosting

  3. 回答「是」(實驗功能)」

  4. 選擇要託管的來源目錄,這可能是現有的 Angular 應用程式。

  5. 如果出現提示,請選擇 Angular。

初始化現有專案

請變更 firebase.json 中的代管設定,以便使用 source 選項,而非 public 選項。例如:

{
  "hosting": {
    "source": "./path-to-your-angular-workspace"
  }
}

提供靜態內容

初始化 Firebase 後,您可以使用標準部署指令提供靜態內容:

firebase deploy

預先轉譯動態內容

如要在 Angular 中預先轉譯動態內容,您必須設定 Angular Universal。Firebase CLI 預期 Express Engine 會:

ng add @nguniversal/express-engine

詳情請參閱 Angular Universal 指南

新增預先顯示網址

根據預設,系統只會預先轉譯根目錄。您可以找出 angular.json 中的預先轉譯步驟,然後新增更多路徑:

{
  "prerender": {
    "builder": "@nguniversal/builders:prerender",
    "options": {
      "routes": ["/", "ANOTHER_ROUTE", "AND_ANOTHER"]
    },
    "configurations": {
      /* ... */
    },
    "defaultConfiguration": "production"
  }
}

如果您需要進一步自訂,Firebase 也會採用代管根目錄中的 guessRoutesroutes.txt 檔案。如要進一步瞭解這些選項,請參閱 Angular 預先算繪指南

選用:新增伺服器模組

部署

使用 firebase deploy 部署時,Firebase 會建構瀏覽器套件、伺服器套件,並預先算繪應用程式。這些元素會部署至 HostingCloud Functions for Firebase

自訂部署

Firebase CLI 會假設您在包含正式版設定的配置圖中,有伺服器、建構和預先算繪步驟。

如要調整 CLI 的假設,請設定 ng deploy,然後編輯 angular.json 中的設定。舉例來說,您可以移除 serverTarget,藉此停用 SSR,並專門提供預先算繪的內容:

{
  "deploy": {
    "builder": "@angular/fire:deploy",
    "options": {
      "browserTarget": "app:build:production",
      "serverTarget": "app:server:production",
      "prerenderTarget": "app:prerender:production"
    }
  }
}

選用:整合 Firebase JS SDK

在伺服器和用戶端套件中加入 Firebase JS SDK 方法時,請先檢查 isSupported(),再使用產品,以防發生執行階段錯誤。並非所有產品都支援所有環境

選用:整合 Firebase Admin SDK

如果管理員套件包含在瀏覽器版本中,就會失敗,因此建議您在伺服器模組中提供這些套件,並以選用依附元件的方式注入:

// your-component.ts
import type { app } from 'firebase-admin';
import { FIREBASE_ADMIN } from '../app.module';

@Component({...})
export class YourComponent {

  constructor(@Optional() @Inject(FIREBASE_ADMIN) admin: app.App) {
    ...
  }
}

// app.server.module.ts
import * as admin from 'firebase-admin';
import { FIREBASE_ADMIN } from './app.module';

@NgModule({
  …
  providers: [
    …
    { provide: FIREBASE_ADMIN, useFactory: () => admin.apps[0] || admin.initializeApp() }
  ],
})
export class AppServerModule {}

// app.module.ts
import type { app } from 'firebase-admin';

export const FIREBASE_ADMIN = new InjectionToken<app.App>('firebase-admin');

使用 SSR 提供完全動態內容

選用:整合 Firebase 驗證

支援網路架構的 Firebase 部署工具會自動使用 Cookie 讓用戶端和伺服器狀態保持同步。Express res.locals 物件可選擇包含已驗證的 Firebase 應用程式例項 (firebaseApp) 和目前登入的使用者 (currentUser)。您可以透過 REQUEST 符記 (從 @nguniversal/express-engine/tokens 匯出) 將此物件插入模組。