Communityコーディング&開発github.com

THE3RDTRAINER/Homepage

インストール済みのFirebase Extension(または拡張機能ソース)を、スタンドアロンのCloud Functions for Firebaseコードベースまたは公開可能なnpmパッケージに変換するスキルです。V1からV2へのトリガーアップグレード、ライフサイクルフック、宣言的セキュリティ設定を含みます。

Homepage とは?

このスキルは、Firebase Extensionを2つの形態のいずれかに移行するための包括的なガイドです。1つ目は、ユーザーのアプリに直接統合可能なローカルCloud Functionsコードベース(`functions/src/`)への変換。2つ目は、V2関数をエクスポートする再利用可能なオープンソースnpmパッケージとしての公開です。このスキルは、宣言的IAM(`requiresRole`)、Google APIの有効化(`requiresAPI`)、パラメータ化された設定(`defineString`など)、SDKライフサイクルフックなど、Cloud Functionsのネイティブ機能を最大限に活用します。また、1st Genトリガーを2nd Genに最新化し、Destructuring Compatibility Shimを使用してレガシーハンドラーとの互換性を維持します。厳格なルールとして、トップレベルモジュール読み込みスコープでの`.value()`呼び出しを禁止し、コスト最適化のためにV2同時実行数を制御する`cpu:

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/THE3RDTRAINER/Homepage/tree/HEAD/.agents/skills/extension-to-functions-codebase

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

拡張機能から関数コードベースおよびnpmパッケージへの移行

概要

Firebase Extensionを次のいずれかに移行します。

  1. ローカルCloud Functionsコードベース(アプリ統合用のfunctions/src/)
  2. 公開可能なnpmパッケージ(V2関数をエクスポートする再利用可能なオープンソースパッケージ)

ネイティブCloud Functions機能(宣言的IAM、パラメータ化された構成、SDKライフサイクルフック)を活用し、Destructuring Compatibility Shimを使用して第1世代トリガーを第2世代に最新化します。


対象移行ワークフロー

  • 対象A: ローカル関数コードベース(エンドユーザーアプリ統合)

    • 出力: functions/src/ 配下のコード。設定は .env 内。
    • デプロイ: firebase deploy --only functions
  • 対象B: 公開可能なnpmパッケージ / 共有可能なパッケージ

    • 出力: V2関数をエクスポートする再利用可能なnpmパッケージ
    • 構成: exports マップ、engines: { "node": ">=22" }、peerDependencies: { "firebase-functions": ">=6.0.0" } を指定した package.json
    • 使用方法: 利用者はパッケージをインストールし、index.ts (export * from "<package-name>") で関数を再エクスポートします。

コアルールと制約

1. 宣言的IAMとAPI(ローカルオーバーヘッドゼロ)

手動の gcloud スクリプトやコンソール指示ではなく、ネイティブSDK宣言を使用します。

  • 必要なGCP IAM権限には requiresRole("roles/...") を使用します。
  • Google APIには requiresAPI("service.googleapis.com", "Description") を使用します。

2. グローバルパラメータアクセス制限

  • トップレベルのモジュール読み込みスコープで決して .value() を呼び出さないでください。
  • グローバルSDKインスタンスは onInit() 内または遅延ゲッターで初期化します。
    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: 拡張機能リソースの棚卸し

  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"
    }
    
  • ESM/CommonJSとTypeScript宣言(lib/index.js、lib/index.d.ts)を対象とする exports マップを構成します。

ステップ3: トリガーをV1からV2にアップグレード

  • Firestore: firebase-functions/v2/firestore の onDocumentWritten を使用します。
  • タスク: firebase-functions/v2/tasks の onTaskDispatched を使用します。タスクをキューに入れる際に EXT_INSTANCE_ID を削除します。
  • HTTP: firebase-functions/v2/https の onRequest を使用します。
  • レガシー第1世代ハンドラーが (change, context) を期待する場所で、Destructuring Compatibility Shim({ change, context }、{ snapshot, context })を適用します。

ステップ4: ライフサイクルイベントの変換

拡張機能のライフサイクルイベントを 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. 変更点(拡張機能 vs パッケージ)比較テーブル

注意: 決して npm publish を実行しないでください。

Individual skills in this repo

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

関連スキル