くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Cloud Functionsの高速化をTypeScriptで試してみた

以下の記事を読んで、実行される関数ごとにファイルを分けて、 呼び出されたときに関数名から必要なファイルだけを読み込むのがいいらしい。

JavaScriptの記事だったので、TypeScriptで試してみた。

ディレクトリ構成

ディレクトリ構成はこんな感じ。

firebase init functionsでTypeScriptを選択した状態。

myproject
 +- functions/                   # functionsのルートディレクトリ
      +- package.json
      +- tsconfig.json
      +- src/                    # TypeScriptのソースディレクトリ
      |   +- modules             # それぞれのfunctionのソースを配置するディレクトリ
      |       +- onCreateUser.ts # それぞれのfunctionのソース
      |   +- index.ts            # Cloud Functionのメイン
      +- lib/
          +- index.js            # コンパイルされたJavaScriptのコード

src/index.ts

import * as functions from "firebase-functions";

// 関数名とファイルパスのペア
const funcs = {
  onCreateUser: "./modules/onCreateUser",
};

// funcsで定義した内容をexportsに追加する
for (let name in funcs) {
  // 環境変数の関数名を見て、funcsの関数名と同じなら、呼び出す判定を追加
  if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === name) {
    // "exports.onCreateUser = require("./modules/onCreateUser").default;"と一緒
    exports[name] = require(funcs[name]).default;
  }
}

src/modules/onCreateUser.ts

ユーザが追加されたらカウントアップする例。

import * as functions from "firebase-functions";

export default functions.firestore
  .document("users/{uid}")
  .onCreate((snapshot, context) => {
    const db = snapshot.ref.firestore;
    const FieldValue = admin.firestore.FieldValue;
   
    const docRef = db.collection("counter").doc("users");
    docRef.update({ userNum: FieldValue.increment(1)});
  });

adminの初期化をこっちに含めると、初期化が重複するため、
snapshotのrefからfirestoreを取得してる。

初期化するのであれば、src/index.tsで初期化するのがいいかも。

import * as admin from "firebase-admin";
admin.initializeApp();

デプロイ

あとは、いつもどおり、myproject/で、

$ npm run deploy -prefix functions

などしてデプロイすればOK!

以上!!

参考にしたサイト様