extension-to-functions-codebase

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Extension to Functions Codebase & npm Package Migration

将Firebase Extension迁移为Functions代码库与可发布npm包

Overview

概述

Migrates a Firebase Extension into either:
  1. A local Cloud Functions codebase (
    functions/src/
    for app integration).
  2. A publishable npm package (reusable open-source package exporting V2 functions).
Leverages native Cloud Functions features (declarative IAM, Parameterized Config, SDK Lifecycle Hooks) and modernizes 1st Gen triggers to 2nd Gen using the Destructuring Compatibility Shim.

将Firebase Extension迁移为以下两种形式之一:
  1. 本地Cloud Functions代码库
    functions/src/
    ,用于应用集成)。
  2. 可发布的npm包(可复用的开源包,导出V2版本函数)。
利用Cloud Functions原生功能(声明式IAM、参数化配置、SDK生命周期钩子),并通过解构兼容垫片将第一代触发器升级为第二代。

Target Migration Workflows

目标迁移工作流

  • Target A: Local Functions Codebase (End-User App Integration)
    • Output: Code under
      functions/src/
      . Config in
      .env
      .
    • Deployment:
      firebase deploy --only functions
      .
  • Target B: Publishable npm Package / Shareable Package
    • Output: Reusable npm package exporting V2 functions.
    • Configuration:
      package.json
      specifying
      exports
      map,
      engines: { "node": ">=22" }
      , and
      peerDependencies: { "firebase-functions": ">=6.0.0" }
      .
    • Usage: Consumers install package and re-export functions in
      index.ts
      (
      export * from "<package-name>"
      ).

  • 目标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>"
      )。

Core Rules & Constraints

核心规则与约束

1. Declarative IAM & APIs (Zero-Local-Overhead)

1. 声明式IAM与API(零本地开销)

Use native SDK declarations instead of manual
gcloud
scripts or console instructions:
  • Use
    requiresRole("roles/...")
    for required GCP IAM permissions.
  • Use
    requiresAPI("service.googleapis.com", "Description")
    for Google APIs.
使用原生SDK声明替代手动
gcloud
脚本或控制台操作说明:
  • 使用
    requiresRole("roles/...")
    配置所需的GCP IAM权限。
  • 使用
    requiresAPI("service.googleapis.com", "Description")
    配置Google API。

2. Global Parameter Access Restriction

2. 全局参数访问限制

  • Never call
    .value()
    at top-level module load scope.
  • Initialize global SDK instances inside
    onInit()
    or lazy getters:
    typescript
    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() });
    });
  • 绝对不要在顶级模块加载作用域中调用
    .value()
  • onInit()
    或惰性获取器中初始化全局SDK实例:
    typescript
    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 Concurrency & Cost Parity

3. V2并发与成本一致性

V2 enables concurrency (up to 80 requests). To preserve V1 single-concurrency pricing, set
cpu: "gcf_gen1"
.

V2支持并发处理(最多80个请求)。如需保留V1单并发定价,设置
cpu: "gcf_gen1"

Step-by-Step Migration Execution

分步迁移执行指南

Step 1: Inventory Extension Resources

步骤1:盘点Extension资源

  1. extension.yaml
    :
    • params
      defineString
      ,
      defineInt
      ,
      defineBoolean
      ,
      defineSecret
      .
    • apis
      requiresAPI(...)
      .
    • roles
      requiresRole(...)
      .
    • lifecycleEvents
      afterFirstDeploy
      &
      afterRedeploy
      .
    • resources
      → Upgrade 1st Gen triggers to 2nd Gen (
      onDocumentWritten
      ,
      onTaskDispatched
      ,
      onRequest
      ).
  2. Files & Scripts: Preserve devDependencies, test framework (
    jest
    ), and test scripts.
  1. extension.yaml
    • params
      → 转换为
      defineString
      defineInt
      defineBoolean
      defineSecret
    • apis
      → 转换为
      requiresAPI(...)
    • roles
      → 转换为
      requiresRole(...)
    • lifecycleEvents
      → 转换为
      afterFirstDeploy
      afterRedeploy
    • resources
      → 将第一代触发器升级为第二代(
      onDocumentWritten
      onTaskDispatched
      onRequest
      )。
  2. 文件与脚本:保留devDependencies、测试框架(
    jest
    )以及测试脚本。

Step 2: Configure
package.json

步骤2:配置
package.json

  • Set
    name: "<package-name>"
    ,
    engines: { "node": ">=22" }
    .
  • Set
    peerDependencies
    :
    json
    "peerDependencies": {
      "firebase-admin": "^11.0.0 || ^12.0.0",
      "firebase-functions": ">=6.0.0"
    }
  • Configure
    exports
    map targeting ESM/CommonJS and TypeScript declarations (
    lib/index.js
    ,
    lib/index.d.ts
    ).
  • 设置
    name: "<package-name>"
    engines: { "node": ">=22" }
  • 设置
    peerDependencies
    json
    "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
    )。

Step 3: Upgrade Triggers from V1 to V2

步骤3:将触发器从V1升级到V2

  • Firestore: Use
    onDocumentWritten
    from
    firebase-functions/v2/firestore
    .
  • Tasks: Use
    onTaskDispatched
    from
    firebase-functions/v2/tasks
    . Remove
    EXT_INSTANCE_ID
    when enqueueing tasks.
  • HTTP: Use
    onRequest
    from
    firebase-functions/v2/https
    .
  • Apply Destructuring Compatibility Shim (
    { change, context }
    ,
    { snapshot, context }
    ) where legacy 1st Gen handlers expect
    (change, context)
    .
  • Firestore:使用
    firebase-functions/v2/firestore
    中的
    onDocumentWritten
  • 任务:使用
    firebase-functions/v2/tasks
    中的
    onTaskDispatched
    。入队任务时移除
    EXT_INSTANCE_ID
  • HTTP:使用
    firebase-functions/v2/https
    中的
    onRequest
  • 在遗留第一代处理器期望
    (change, context)
    参数的位置,应用解构兼容垫片(
    { change, context }
    { snapshot, context }
    )。

Step 4: Convert Lifecycle Events

步骤4:转换生命周期事件

Map extension lifecycle events to SDK lifecycle hooks in
src/index.ts
:
  • onInstall
    afterFirstDeploy({ task: { function: "initTask" } })
  • onUpdate
    /
    onConfigure
    afterRedeploy({ task: { function: "setupTask" } })
将Extension生命周期事件映射到
src/index.ts
中的SDK生命周期钩子:
  • onInstall
    afterFirstDeploy({ task: { function: "initTask" } })
  • onUpdate
    /
    onConfigure
    afterRedeploy({ task: { function: "setupTask" } })

Step 5: Package README & Export Instructions

步骤5:包的README与导出说明

Generate
README.md
containing:
  1. Installation instructions (
    npm install
    ).
  2. Re-export snippet (
    export * from "<package-name>"
    ).
  3. Parameterized Configuration
    .env
    reference table.
  4. What Changed (Extension vs Package) comparison table.
Reminder: NEVER execute
npm publish
.
生成
README.md
文件,包含:
  1. 安装说明(
    npm install
    )。
  2. 重新导出代码片段(
    export * from "<package-name>"
    )。
  3. 参数化配置
    .env
    参考表。
  4. 变更对比表(Extension vs 包)。
提醒:绝对不要执行
npm publish