TypeScript の Azure Functions アプリをビルドしてデプロイする

Azure Functionsは、TypeScriptアプリをAzureに公開するための複数のビルドオプションをサポートしています。 ビルド方法をローカル環境、アプリの依存関係、TypeScriptのコンパイル要件、ランタイムの要件に基づいて選びましょう。

ビルド方法の選択

要因 現地でのビルド (推奨) リモートビルド
最適な用途 複雑なビルド、モノレポ、カスタムツール シンプルなプロジェクト、迅速なデプロイ
パッケージのサイズ より大きい( node_modulesを含む) より小さい(依存関係は Azure にインストール)
TypeScriptコンパイル ローカルでコンパイルします Azureは自動的にコンパイルします
ネイティブバイナリ互換性 ターゲットのアーキテクチャに一致しなければなりません 自動処理(Linux x64)
タイムアウトリスクを上げる なし(あなたのマシン上で動作) 大きな依存集合で可能
コントロール フル(ビルドツール、バンドラー、最適化ツールなど全て) プラットフォームのデフォルトに限定されます

プライベートnpmパッケージやカスタムレジストリについては、「 カスタム依存関係」を参照してください。

デプロイメントのためにアプリをパッケージ化しましょう

TypeScript関数アプリをAzureにデプロイする際、デプロイパッケージは以下の要件を満たす必要があります:

  • JavaScript出力が必要です:Azure FunctionsはJavaScriptを実行するため、TypeScriptはデプロイ前またはデプロイ中にコンパイルする必要があります。

  • ルート レベルの host.json: 1 つの host.json ファイルが、サブフォルダーに入れ子ではなく、展開パッケージのルートにあることを確認します。

  • package.json main フィールド:Functionsランタイムは起動時にこのフィールドを読み取り、関数の位置を特定してインデックスします。 コンパイルされたJavaScriptのエントリポイント(例: dist/src/index.js)を指し示さなければなりません。

  • 開発ファイルの除外: .funcignore ファイルを使って不要なファイルを展開から除外します。例のように:

    .git/
    .vscode/
    local.settings.json
    test/
    .env
    tsconfig.json
    src/
    node_modules/
    

また、展開計画の際には以下のトレードオフも念頭に置いてください。

  • ビルド環境は本番環境に合わせる必要があります:ネイティブバイナリを持つ依存関係はLinux x64アーキテクチャ向けに構築されなければなりません。 リモートビルドは これを自動で処理します。 ローカルビルドの場合は、Dockerやコンテナ化されたビルド環境の使用を検討してください。
  • デプロイメントパッケージのサイズはコールドスタートに影響します:依存関係セットが大きいほど、ランタイムで各ファイルを個別にロードしなければならないためコールドスタートの遅延が増加します。 esbuildやwebpackのようなツールで、アプリを少ないファイルにまとめることで、起動時間を大幅に短縮できます。
  • リモートビルドにはタイムアウト制限があります:依存関係のインストールやTypeScriptのコンパイルがプラットフォームの制限を超えると、ビルドは失敗します。 大規模なプロジェクトには、あらかじめ依存関係を持つ ローカルビルド を使いましょう。
  • モジュール初期化には時間制限があり、起動時 Node.js モジュールのロードと関数インデックス作成は時間制限があります。 可能であればトップレベルのインポートを減らすか、動的インポートを活用しましょう。

ローカル ビルド

リモートビルドを明示的にリクエストしなければ、マシンは依存関係をインストールしてTypeScriptをコンパイルします。 その後、コンパイル済みのプロジェクト全体と依存関係をローカルでファンクションアプリにパッケージ化・デプロイします。

ローカルビルドはパッケージのアップロード量を大きくしますが、ビルドプロセスを完全にコントロールでき、開発環境との互換性を確保します。

ローカルビルドを使用するTypeScriptプロジェクトの場合:

  1. TypeScriptの事前コンパイル:展開前にローカルでTypeScriptコードをコンパイルします。
  2. 依存関係をインストールする: npm install または yarn install を実行して、ローカルで依存関係をインストールしましょう。
  3. ビルド検証:ビルド出力がローカル環境で正しく動作するか確認しましょう。
  4. コンパイル済み出力をデプロイする:コンパイル済みJavaScriptと依存関係を展開します。

ローカル ビルド用のビルド コマンドの例:

# Install dependencies
npm install

# Compile TypeScript
npm run build
# or
tsc

# Deploy with local build (no remote compilation)
func azure functionapp publish <APP_NAME> --no-build

ローカルビルドを使えるように、以下のツールを設定できます:

リモート ビルド

リモートビルドを使う場合、Functionsプラットフォームはパッケージのインストール、TypeScriptのコンパイル、リモートランタイム環境との互換性を確保します。

リモートビルドを使うことで、 node_modules やコンパイルされたJavaScriptファイルを含める必要がなく、より小さなデプロイメントパッケージが得られます。

リモートビルドを使ってTypeScriptプロジェクトをデプロイする場合:

  1. 自動検出:プラットフォームはTypeScriptプロジェクトを、 tsconfig.jsonの存在によって検出します。
  2. コンパイル:プラットフォームはプロジェクトのTypeScript設定を使ってTypeScriptファイルをコンパイルします。
  3. 依存関係のインストール:プラットフォームはdependenciesからdevDependenciespackage.jsonの両方をインストールします。なぜなら、typescriptのようなビルドタイムパッケージはコンパイルに必要だからです。
  4. 最適化:プラットフォームは最終展開パッケージに必要なファイルのみを含みます。

TypeScriptアプリを公開する際には、以下のツールを使ってリモートビルドを利用できます:

Azure Pipelines を使用した継続的デリバリーなど、他のシナリオでリモート ビルドを有効にするには、「リモート ビルドの有効化」を参照してください。

カスタムの依存関係

Azure Functionsはカスタムnpmレジストリ、プライベートパッケージ、ローカルパッケージを使用することで、カスタムおよびプライベートnpm依存関係をサポートしています。

カスタムnpmレジストリを使ったリモートビルド

プライベートパッケージがカスタムnpmレジストリで利用可能になった場合、レジストリの場所を設定した後にリモートビルドをリクエストできます。

カスタムレジストリを使用するには、プロジェクトのルートに .npmrc ファイルを作成します:

registry=https://your-private-registry.com/
//your-private-registry.com/:_authToken=${NPM_TOKEN}

ローカルパッケージとプライベートモジュール

TypeScript Azure Functionアプリを構築する際には、ローカルパッケージやプライベートモジュールがサポートされています。

リモートビルドでローカルパッケージを含めるには、package.jsonファイル内で参照してください:

{
  "dependencies": {
    "@azure/functions": "^4.0.0",
    "my-private-package": "file:../my-private-package",
    "another-local-package": "file:./packages/local-lib"
  }
}

ローカルビルドでローカル依存関係を含めるには、依存関係をローカルにインストールし、リモートビルドを無効にしてデプロイしてください:

# Install all dependencies including local ones
npm install

# Build your TypeScript project
npm run build

# Publish with local build
func azure functionapp publish <APP_NAME> --no-build

ワークスペースパッケージの使用

モノリポジトリやnpmワークスペースの設定では、 package.json ファイル内のnpmワークスペースを使って共有パッケージを参照してください:

{
  "name": "functions-app",
  "dependencies": {
    "@azure/functions": "^4.0.0",
    "@mycompany/shared-lib": "workspace:*"
  },
  "workspaces": [
    "packages/*"
  ]
}

展開前にバンドルしてください

webpack、esbuild、rollupなどのバンドルツールを使って、デプロイ前に単一のバンドルを作成しましょう:

# Bundle your application
npm run bundle

# Deploy the bundled output
func azure functionapp publish <APP_NAME> --no-build