Extension 轉換為 Functions 程式碼庫與 npm 套件遷移
概述
將 Firebase Extension 遷移為以下兩種形式之一:
- 本機 Cloud Functions 程式碼庫(
functions/src/,供應用程式整合)。 - 可發布的 npm 套件(可重複使用的開源套件,匯出 V2 函式)。
利用 Cloud Functions 的原生功能(宣告式 IAM、參數化設定、SDK 生命週期鉤子),並透過解構相容墊片將第 1 代觸發器現代化升級為第 2 代。
目標遷移工作流程
-
目標 A:本機 Functions 程式碼庫(終端使用者應用程式整合)
- 輸出:
functions/src/下的程式碼。設定檔位於.env。 - 部署:
firebase deploy --only functions。
- 輸出:
-
目標 B:可發布的 npm 套件 / 可分享套件
- 輸出:可重複使用的 npm 套件,匯出 V2 函式。
- 設定:
package.json需指定exports地圖、engines: { "node": ">=22" }以及peerDependencies: { "firebase-functions": ">=6.0.0" }。 - 使用方式:使用者安裝套件後,在
index.ts中重新匯出函式(export * from "<package-name>")。
核心規則與限制
1. 宣告式 IAM 與 API(零本地負擔)
使用原生 SDK 宣告取代手動的 gcloud 指令或主控台指示:
- 使用
requiresRole("roles/...")指定所需的 GCP IAM 權限。 - 使用
requiresAPI("service.googleapis.com", "Description")指定 Google API。
2. 全域參數存取限制
- 絕不在模組頂層載入範圍內呼叫
.value()。 - 在
onInit()或惰性取值器中初始化全域 SDK 實例:import { defineString } from "firebase-functions/params"; import { onInit } from "firebase-functions/v2"; const dataset = defineString("DATASET_ID"); let client: BigQuery; onInit(() => { client = new BigQuery({ datasetId: dataset.value() }); });
3. V2 並行性與成本一致性
V2 啟用並行性(最多 80 個請求)。若要保留 V1 的單一並行定價,請設定 cpu: "gcf_gen1"。
逐步遷移執行
步驟 1:盤點 Extension 資源
extension.yaml:params→defineString,defineInt,defineBoolean,defineSecret。apis→requiresAPI(...)。roles→requiresRole(...)。lifecycleEvents→afterFirstDeploy與afterRedeploy。resources→ 將第 1 代觸發器升級為第 2 代(onDocumentWritten、onTaskDispatched、onRequest)。
- 檔案與指令碼:保留 devDependencies、測試框架(
jest)及測試指令碼。
步驟 2:設定 package.json
- 設定
name: "<package-name>"、engines: { "node": ">=22" }。 - 設定
peerDependencies:"peerDependencies": { "firebase-admin": "^11.0.0 || ^12.0.0", "firebase-functions": ">=6.0.0" } - 設定
exports地圖,指向 ESM/CommonJS 及 TypeScript 宣告檔(lib/index.js、lib/index.d.ts)。
步驟 3:將觸發器從 V1 升級至 V2
- Firestore:使用來自
firebase-functions/v2/firestore的onDocumentWritten。 - Tasks:使用來自
firebase-functions/v2/tasks的onTaskDispatched。排程任務時移除EXT_INSTANCE_ID。 - HTTP:使用來自
firebase-functions/v2/https的onRequest。 - 在舊版第 1 代處理器預期使用
(change, context)的地方,套用解構相容墊片({ change, context }、{ snapshot, context })。
步驟 4:轉換生命週期事件
將 Extension 生命週期事件對應至 src/index.ts 中的 SDK 生命週期鉤子:
onInstall→afterFirstDeploy({ task: { function: "initTask" } })onUpdate/onConfigure→afterRedeploy({ task: { function: "setupTask" } })
步驟 5:套件 README 與匯出指示
產生 README.md,內容包含:
- 安裝說明(
npm install)。 - 重新匯出程式碼片段(
export * from "<package-name>")。 - 參數化設定
.env參考表格。 - 異動說明(Extension 與套件對比)表格。
提醒:絕對不要執行 npm publish。