Migration d'Extension vers Codebase Functions & Package npm
Aperçu
Migre une extension Firebase en soit :
- Une codebase Cloud Functions locale (
functions/src/pour l'intégration applicative). - Un package npm publiable (package open-source réutilisable exportant des fonctions V2).
Exploite les fonctionnalités natives de Cloud Functions (IAM déclaratif, configuration paramétrée, hooks de cycle de vie SDK) et modernise les déclencheurs 1ère génération vers la 2ème génération à l'aide de la couche de compatibilité par déstructuration.
Workflows de Migration Cible
-
Cible A : Codebase Functions Locale (Intégration Application Utilisateur Finale)
- Sortie : Code sous
functions/src/. Configuration dans.env. - Déploiement :
firebase deploy --only functions.
- Sortie : Code sous
-
Cible B : Package npm Publiable / Package Partageable
- Sortie : Package npm réutilisable exportant des fonctions V2.
- Configuration :
package.jsonspécifiant une mapexports,engines: { "node": ">=22" }, etpeerDependencies: { "firebase-functions": ">=6.0.0" }. - Utilisation : Les consommateurs installent le package et ré-exportent les fonctions dans
index.ts(export * from "<nom-du-package>").
Règles et Contraintes Fondamentales
1. IAM & APIs Déclaratifs (Aucun Surcharge Locale)
Utilisez les déclarations natives du SDK au lieu de scripts gcloud manuels ou d'instructions console :
- Utilisez
requiresRole("roles/...")pour les permissions IAM GCP requises. - Utilisez
requiresAPI("service.googleapis.com", "Description")pour les APIs Google.
2. Restriction d'Accès Global aux Paramètres
- N'appelez jamais
.value()au niveau de la portée de chargement du module principal. - Initialisez les instances globales du SDK à l'intérieur de
onInit()ou de getters paresseux :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. Parité de Concurrence et de Coût V2
V2 active la concurrence (jusqu'à 80 requêtes). Pour préserver la tarification mono-concurrence V1, définissez cpu: "gcf_gen1".
Exécution de la Migration Étape par Étape
Étape 1 : Inventaire des Ressources de l'Extension
extension.yaml:params→defineString,defineInt,defineBoolean,defineSecret.apis→requiresAPI(...).roles→requiresRole(...).lifecycleEvents→afterFirstDeploy&afterRedeploy.resources→ Mettre à niveau les déclencheurs 1ère génération vers la 2ème génération (onDocumentWritten,onTaskDispatched,onRequest).
- Fichiers et Scripts : Préservez les devDependencies, le framework de test (
jest) et les scripts de test.
Étape 2 : Configuration du package.json
- Définissez
name: "<nom-du-package>",engines: { "node": ">=22" }. - Définissez
peerDependencies:"peerDependencies": { "firebase-admin": "^11.0.0 || ^12.0.0", "firebase-functions": ">=6.0.0" } - Configurez la map
exportsciblant ESM/CommonJS et les déclarations TypeScript (lib/index.js,lib/index.d.ts).
Étape 3 : Mise à Niveau des Déclencheurs de V1 vers V2
- Firestore : Utilisez
onDocumentWrittendepuisfirebase-functions/v2/firestore. - Tasks : Utilisez
onTaskDispatcheddepuisfirebase-functions/v2/tasks. SupprimezEXT_INSTANCE_IDlors de la mise en file d'attente des tâches. - HTTP : Utilisez
onRequestdepuisfirebase-functions/v2/https. - Appliquez la couche de compatibilité par déstructuration (
{ change, context },{ snapshot, context }) là où les gestionnaires hérités 1ère génération attendent(change, context).
Étape 4 : Conversion des Événements de Cycle de Vie
Mappez les événements de cycle de vie de l'extension vers les hooks de cycle de vie du SDK dans src/index.ts :
onInstall→afterFirstDeploy({ task: { function: "initTask" } })onUpdate/onConfigure→afterRedeploy({ task: { function: "setupTask" } })
Étape 5 : README du Package et Instructions d'Export
Générez README.md contenant :
- Instructions d'installation (
npm install). - Extrait de ré-exportation (
export * from "<nom-du-package>"). - Tableau de référence de la configuration paramétrée
.env. - Tableau de comparaison Ce qui a Changé (Extension vs Package).
Rappel : N'exécutez JAMAIS npm publish.