Migração de Extensão para Base de Código Functions e Pacote npm
Visão Geral
Migra uma Extensão do Firebase para:
- Uma base de código local do Cloud Functions (
functions/src/para integração com o aplicativo). - Um pacote npm publicável (pacote open-source reutilizável exportando funções V2).
Aproveita recursos nativos do Cloud Functions (IAM declarativo, Configuração Parametrizada, Hooks de Ciclo de Vida do SDK) e moderniza triggers de 1ª Geração para 2ª Geração usando o Shim de Compatibilidade por Desestruturação.
Fluxos de Migração Alvo
-
Alvo A: Base de Código Functions Local (Integração com Aplicativo do Usuário Final)
- Saída: Código em
functions/src/. Configuração em.env. - Implantação:
firebase deploy --only functions.
- Saída: Código em
-
Alvo B: Pacote npm Publicável / Pacote Compartilhável
- Saída: Pacote npm reutilizável exportando funções V2.
- Configuração:
package.jsonespecificando mapaexports,engines: { "node": ">=22" }epeerDependencies: { "firebase-functions": ">=6.0.0" }. - Uso: Consumidores instalam o pacote e re-exportam funções em
index.ts(export * from "<nome-do-pacote>").
Regras e Restrições Principais
1. IAM e APIs Declarativos (Zero-Sobrecarga-Local)
Use declarações nativas do SDK em vez de scripts gcloud manuais ou instruções de console:
- Use
requiresRole("roles/...")para permissões IAM necessárias do GCP. - Use
requiresAPI("service.googleapis.com", "Descrição")para APIs do Google.
2. Restrição de Acesso a Parâmetros Globais
- Nunca chame
.value()no escopo de carregamento do módulo de nível superior. - Inicialize instâncias globais do SDK dentro de
onInit()ou getters preguiçosos: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. Concorrência V2 e Paridade de Custo
V2 permite concorrência (até 80 requisições). Para preservar o preço de concorrência única V1, defina cpu: "gcf_gen1".
Execução da Migração Passo a Passo
Passo 1: Inventariar Recursos da Extensão
extension.yaml:params→defineString,defineInt,defineBoolean,defineSecret.apis→requiresAPI(...).roles→requiresRole(...).lifecycleEvents→afterFirstDeploy&afterRedeploy.resources→ Atualizar triggers de 1ª Geração para 2ª Geração (onDocumentWritten,onTaskDispatched,onRequest).
- Arquivos e Scripts: Preservar devDependencies, estrutura de teste (
jest) e scripts de teste.
Passo 2: Configurar package.json
- Definir
name: "<nome-do-pacote>",engines: { "node": ">=22" }. - Definir
peerDependencies:"peerDependencies": { "firebase-admin": "^11.0.0 || ^12.0.0", "firebase-functions": ">=6.0.0" } - Configurar mapa
exportsdirecionando ESM/CommonJS e declarações TypeScript (lib/index.js,lib/index.d.ts).
Passo 3: Atualizar Triggers de V1 para V2
- Firestore: Usar
onDocumentWrittendefirebase-functions/v2/firestore. - Tasks: Usar
onTaskDispatcheddefirebase-functions/v2/tasks. RemoverEXT_INSTANCE_IDao enfileirar tarefas. - HTTP: Usar
onRequestdefirebase-functions/v2/https. - Aplicar Shim de Compatibilidade por Desestruturação (
{ change, context },{ snapshot, context }) onde handlers legados de 1ª Geração esperam(change, context).
Passo 4: Converter Eventos do Ciclo de Vida
Mapear eventos do ciclo de vida da extensão para hooks de ciclo de vida do SDK em src/index.ts:
onInstall→afterFirstDeploy({ task: { function: "initTask" } })onUpdate/onConfigure→afterRedeploy({ task: { function: "setupTask" } })
Passo 5: README do Pacote e Instruções de Exportação
Gerar README.md contendo:
- Instruções de instalação (
npm install). - Trecho de re-exportação (
export * from "<nome-do-pacote>"). - Tabela de referência da Configuração Parametrizada
.env. - Tabela de comparação O que Mudou (Extensão vs Pacote).
Lembrete: NUNCA execute npm publish.