Community程式設計與開發github.com

擴充功能轉換為 Functions 程式碼庫與 npm 套件遷移

將已安裝的 Firebase 擴充功能(或擴充功能原始碼)轉換為獨立的 Cloud Functions for Firebase 程式碼庫或可發行的 npm 套件,包含 V1 到 V2 觸發器升級、生命週期鉤子與宣告式安全性設定。

擴充功能轉換為 Functions 程式碼庫與 npm 套件遷移 是什麼?

此技能旨在幫助開發者將 Firebase 擴充功能(Extension)遷移為兩種目標形式之一:一是可整合至應用程式的本機 Cloud Functions 程式碼庫(`functions/src/`),二是可發布的 npm 套件(可重複使用的開源套件並匯出 V2 函式)。它利用 Cloud Functions 的原生功能,如宣告式 IAM(`requiresRole`)、參數化設定(`defineString`)以及 SDK 生命週期鉤子(`onInit`),並透過解構相容墊片(Destructuring Compatibility Shim)將第一代觸發器現代化升級為第二代。此技能支援 Cursor、Claude Code 等平台,擅長處理 `extension.yaml` 的解析、`package.json` 的設定(含 `peerDependencies` 與 `exports` 地圖)、觸發器升級(Firestore、Tasks、HTTP)以及生命週期事件的轉換(`onInstall` → `afterFirstDeploy`)。它嚴格遵循安全規則:禁止在模組頂層呼叫 `.value()`、使用 `cpu: "gcf_gen1"` 保持 V1 的費用結構,並生成完整的 README 與匯出指示。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/momabrouk18-eng/Website/tree/HEAD/.agents/skills/extension-to-functions-codebase

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Extension 轉換為 Functions 程式碼庫與 npm 套件遷移

概述

將 Firebase Extension 遷移為以下兩種形式之一:

  1. 本機 Cloud Functions 程式碼庫(functions/src/,供應用程式整合)。
  2. 可發布的 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 資源

  1. extension.yaml:
    • params → defineString, defineInt, defineBoolean, defineSecret。
    • apis → requiresAPI(...)。
    • roles → requiresRole(...)。
    • lifecycleEvents → afterFirstDeploy 與 afterRedeploy。
    • resources → 將第 1 代觸發器升級為第 2 代(onDocumentWritten、onTaskDispatched、onRequest)。
  2. 檔案與指令碼:保留 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,內容包含:

  1. 安裝說明(npm install)。
  2. 重新匯出程式碼片段(export * from "<package-name>")。
  3. 參數化設定 .env 參考表格。
  4. 異動說明(Extension 與套件對比)表格。

提醒:絕對不要執行 npm publish。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相關技能