Was macht Extension zu Functions Codebase & npm-Paket-Migration?
Überblick
Wandelt eine Firebase Extension um in entweder:
- Eine lokale Cloud Functions-Codebasis (
functions/src/für die App-Integration). - Ein veröffentlichbares npm-Paket (wiederverwendbares Open-Source-Paket, das V2-Funktionen exportiert).
Nutzt native Cloud Functions-Features (deklaratives IAM, parametrisierte Konfiguration, SDK-Lifecycle-Hooks) und modernisiert Trigger der 1. Generation auf die 2. Generation mithilfe des Destructuring Compatibility Shims.
Ziel-Migrations-Workflows
-
Ziel A: Lokale Functions-Codebasis (Endbenutzer-App-Integration)
- Ausgabe: Code unter
functions/src/. Konfiguration in.env. - Bereitstellung:
firebase deploy --only functions.
- Ausgabe: Code unter
-
Ziel B: Veröffentlichbares npm-Paket / Teilbares Paket
- Ausgabe: Wiederverwendbares npm-Paket, das V2-Funktionen exportiert.
- Konfiguration:
package.jsonmitexports-Map,engines: { "node": ">=22" }undpeerDependencies: { "firebase-functions": ">=6.0.0" }. - Verwendung: Nutzer installieren das Paket und exportieren die Funktionen erneut in
index.ts(export * from "<paket-name>").
Kernregeln & Einschränkungen
1. Deklaratives IAM & APIs (Null-lokaler-Overhead)
Native SDK-Deklarationen anstelle von manuellen gcloud-Skripten oder Konsolenanweisungen verwenden:
requiresRole("roles/...")für erforderliche GCP-IAM-Berechtigungen.requiresAPI("service.googleapis.com", "Beschreibung")für Google-APIs.
2. Einschränkung des globalen Parameterzugriffs
.value()niemals auf Modulebene aufrufen.- Globale SDK-Instanzen innerhalb von
onInit()oder Lazy-Gettern initialisieren: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 & Kostenparität
V2 aktiviert Concurrency (bis zu 80 Anfragen). Um die V1-Einzel-Concurrency-Preisstruktur beizubehalten, setze cpu: "gcf_gen1".
Schritt-für-Schritt-Migrationsausführung
Schritt 1: Extension-Ressourcen inventarisieren
extension.yaml:params→defineString,defineInt,defineBoolean,defineSecret.apis→requiresAPI(...).roles→requiresRole(...).lifecycleEvents→afterFirstDeploy&afterRedeploy.resources→ Upgrade der Trigger der 1. Generation auf die 2. Generation (onDocumentWritten,onTaskDispatched,onRequest).
- Dateien & Skripte: devDependencies, Test-Framework (
jest) und Testskripte beibehalten.
Schritt 2: package.json konfigurieren
- Setze
name: "<paket-name>",engines: { "node": ">=22" }. - Setze
peerDependencies:"peerDependencies": { "firebase-admin": "^11.0.0 || ^12.0.0", "firebase-functions": ">=6.0.0" } - Konfiguriere die
exports-Map für ESM/CommonJS und TypeScript-Deklarationen (lib/index.js,lib/index.d.ts).
Schritt 3: Trigger von V1 auf V2 upgraden
- Firestore:
onDocumentWrittenausfirebase-functions/v2/firestoreverwenden. - Tasks:
onTaskDispatchedausfirebase-functions/v2/tasksverwenden.EXT_INSTANCE_IDbeim Einreihen von Tasks entfernen. - HTTP:
onRequestausfirebase-functions/v2/httpsverwenden. - Destructuring Compatibility Shim anwenden (
{ change, context },{ snapshot, context }), wo Legacy-Handler der 1. Generation(change, context)erwarten.
Schritt 4: Lifecycle-Events konvertieren
Mapping der Extension-Lifecycle-Events auf SDK-Lifecycle-Hooks in src/index.ts:
onInstall→afterFirstDeploy({ task: { function: "initTask" } })onUpdate/onConfigure→afterRedeploy({ task: { function: "setupTask" } })
Schritt 5: Paket-README & Exportanweisungen
Erzeuge README.md mit:
- Installationsanleitung (
npm install). - Re-Export-Ausschnitt (
export * from "<paket-name>"). - Referenztabelle für parametrisierte Konfiguration
.env. - Vergleichstabelle „Was sich geändert hat“ (Extension vs. Paket).
Hinweis: NIEMALS npm publish ausführen.