Cloud Functions に TypeScript を使用する

TypeScript で関数を記述することを必要とするデベロッパーに対して、Cloud Functions では次の 2 つの方法がサポートされています。

  • 初期化時(firebase init functions)に自動的にトランスパイルされる TypeScript プロジェクトを作成して構成する。
  • 事前デプロイフックを使用して、既存の TypeScript ソースをデプロイ時に JavaScript にトランスパイルする。

このガイドの手順に沿って操作すると、既存の JavaScript プロジェクトを TypeScript に移行し、事前デプロイフックを使ってソースコードをトランスパイルして関数をデプロイできます。関数を記述するときは、標準の JavaScript よりも TypeScript を使用したほうが多くの利点があります。

  • TypeScript は async や await といった最新の JavaScript 機能をサポートしているため、Promise の管理が簡素化される
  • Cloud Functions のリンターによって、コーディング中によくある問題が強調表示される
  • データ型のチェック機能によって、デプロイされた関数のランタイム エラーを回避できる

TypeScript を初めてお使いの方は、TypeScript in 5 minutes をご覧ください。

新しい Cloud Functions プロジェクトを TypeScript で初期化する

新しいディレクトリで firebase init functions を実行します。JavaScript と TypeScript のどちらを使ってプロジェクトをビルドするかを選択できます。ここでは TypeScript を選択します。以下のプロジェクト構造が出力されます。

myproject
 +- functions/     # Directory containing all your functions code
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- tsconfig.json
      |
      +- .eslintrc.js # Optional file if you enabled ESLint
      +- tsconfig.dev.json # Optional file that references .eslintrc.js
      |
      +- src/     # Directory containing TypeScript source
      |   |
      |   +- index.ts  # main source file for your Cloud Functions code
      |
      +- lib/
          |
          +- index.js  # Built/transpiled JavaScript code
          |
          +- index.js.map # Source map for debugging

初期化が完了したら、index.ts にあるサンプルのコメント化解除し、npm run serve を実行して「Hello World」が出力されるのを確認します。

既存の TypeScript プロジェクトを使用する

既存の TypeScript プロジェクトがある場合は、事前デプロイフックを追加して、Cloud Functions for Firebase にコードをデプロイするたびにプロジェクトがトランスパイルされるようにすることができます。これを行うには、正しい形式の tsconfig.json ファイルと Firebase プロジェクトが必要です。また、Firebase 構成を次のように変更する必要があります。

  1. package.json を編集して、TypeScript プロジェクトをビルドするための bash スクリプトを追加します。次に例を示します。

     {
       "name": "functions",
       "scripts": {
         "build": "npm run lint && tsc"
       }
     ...
    
  2. firebase.json を編集して、ビルド スクリプトを実行するための事前デプロイフックを追加します。次に例を示します。

     {
       "functions": {
         "predeploy": "npm --prefix functions run build",
       }
     }
    

この構成では、firebase deploy --only functions コマンドが TypeScript コードをビルドし、それを関数としてデプロイします。

既存の JavaScript プロジェクトを TypeScript に移行する

JavaScript で開発された初期化済みの既存の Cloud Functions プロジェクトがある場合は、それを TypeScript に移行できます。作業に先立って、git チェックポイントやその他のバックアップを作成することを強くおすすめします。

既存の JavaScript Cloud Functions プロジェクトを移行するには:

  1. git チェックポイントを作成し、既存の JavaScript ソースファイルのコピーを保存します。
  2. プロジェクト ディレクトリで firebase init functions を実行し、関数を記述する言語を尋ねられたら TypeScript を選択します。
  3. 既存の package.json ファイルを上書きするか確認するよう求められたら、既存のファイルを残す必要がないことがはっきりしていない限り、[いいえ] を選択します。
  4. functions/src ディレクトリの index.ts を既存のソースコードで置き換えて、元のファイルを削除します。
  5. 初期化時に作成された tsconfig.json ファイルで、JavaScript を許可するようにコンパイラ オプションを設定します("allowJs": true)。
  6. 保存した package.json ファイルを functions ディレクトリにコピーし、それを編集して "main" を "lib/index.js" に設定します。
  7. package.json で、次のような TypeScript 用のビルド スクリプトを追加します。

     {
       "name": "functions",
       "scripts": {
         "build": "npm run lint && tsc"
       }
     ...
    
  8. dev の依存関係として "typescript" を追加するため、npm install --save-dev typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser を実行します。

  9. すべての依存関係について、npm install --save @types/<dependency> を実行します。

  10. 必要に応じて、ソースコードを .js から .ts に書き換えます。

TypeScript 関数をエミュレートする

TypeScript 関数をローカルでテストするには、関数をローカルで実行するで説明されているエミュレーション ツールを使用します。このツールを使用するには、事前にコードをコンパイルする必要があります。firebase emulators:start または firebase functions:shell を実行する前に、関数ディレクトリ内で npm run build を実行してください。あるいは、ショートカットとして npm run serve または npm run shell を実行します。いずれのコマンドもビルドを実行し、関数 shell を提供、起動します。

TypeScript プロジェクトの Functions ログ

firebase deploy の実行時に、プロジェクトの index.ts が index.js にトランスパイルされます。つまり、Cloud Functions ログは、デベロッパーが作成したコードではなく index.js ファイルから行番号を出力します。index.ts で対応するパスと行番号を見つけやすくするために、firebase deploy は functions/lib/index.js.map を作成します。このソースマップは、お好みの IDE またはノード モジュールで使用できます。