Turborepoでの環境変数管理完全ガイド
はじめに
モノレポ管理ツールとして人気のTurborepoを使用していると、複数のアプリケーションやパッケージ間での環境変数の扱いに悩むことがあります。この記事では、Turborepoにおける環境変数の管理方法、特にNext.jsアプリケーションでの設定方法を詳しく解説します。
Turborepoにおける環境変数の基本
Turborepoでは、環境変数の管理に関して以下の重要な概念があります:
- env - ビルドキャッシュに影響を与える変数
- passThroughEnv - キャッシュに影響しない変数
- globalDependencies - 全タスクに影響を与えるファイルや環境変数ファイル
- globalEnv - 全タスクで使用される環境変数(Turborepo 2.0 以降)
これらを理解することで、効率的なビルドプロセスを実現できます。
モノレポでの環境変数の配置
Turborepoを使用するプロジェクトでは、環境変数ファイルを以下のように配置できます:
|
|
重要なのは、Turborepoは自動的にルートの.env
ファイルを各ワークスペースに共有しないという点です。
turbo.json での設定 (Turborepo 2.0)
Turborepo 2.0からは、設定ファイルの構造が変更され、pipeline
からtasks
に変わりました。環境変数を適切に管理するには、turbo.json
ファイルで明示的に設定する必要があります:
|
|
envとpassThroughEnvの違い
この設定の中で特に重要なのが、env
とpassThroughEnv
の違いです:
- env:ここに指定された変数の値が変更されると、キャッシュが無効化され、再ビルドが発生します
- passThroughEnv:ここに指定された変数はビルドプロセスに渡されますが、値が変わってもキャッシュに影響しません
例えば、開発環境と本番環境でVERCEL_ENV
の値が異なっていても、API_KEY
が同じであればビルドキャッシュを再利用できます。これにより、CI/CDパイプラインでのビルド時間を大幅に短縮できます。
globalDependenciesとglobalEnvの関係
globalDependencies
とglobalEnv
は異なる目的を持っています:
- globalDependencies:ファイルの変更を検知してキャッシュを無効化しますが、環境変数として自動的に読み込むわけではありません
- globalEnv:全タスクで使用される環境変数を明示的に指定します
例えば、.env
ファイルをglobalDependencies
に指定しただけでは、その中身が環境変数として使用できるわけではありません。.env
内の変数を使うには、各タスクのenv
/passThroughEnv
やglobalEnv
で明示的に指定する必要があります:
|
|
Turborepo 1.x から 2.0 への変更点
Turborepo 2.0では、以下の重要な変更がありました:
pipeline
→tasks
に名前変更globalEnv
が導入され、全タスクで使用される環境変数を指定可能にglobalDependencies
は引き続き外部ファイル依存を指定するために利用- レガシーキャッシングモードの廃止と新しいデフォルトキャッシングの導入
globalEnvの適切な使い方
globalEnv
は便利な機能ですが、無分別に使用するとプロジェクトのビルド効率に悪影響を及ぼす可能性があります:
-
使用を控えるべき場合
globalEnv
に指定した変数が変更されると、すべてのタスクのキャッシュが無効化されます- 特に大規模なモノレポでは、不必要なビルド時間の増加につながります
-
適切な使用例
- システム全体に影響する重要な変数のみを指定する(例:
NODE_ENV
、CI
) - 本当にすべてのアプリ/パッケージで共通して使われる変数のみを指定する
- システム全体に影響する重要な変数のみを指定する(例:
-
ベストプラクティス
- アプリケーション固有の変数は各ワークスペースの
turbo.json
で管理する - 変更の影響範囲を必要最小限に抑え、キャッシュを最大限に活用する
- アプリケーション固有の変数は各ワークスペースの
実践的な環境変数管理テクニック
1. dotenv-cliの活用
複数のワークスペース間で環境変数を確実に共有するには、dotenv-cli
を使うことが効果的です:
|
|
ルートのpackage.json
のスクリプトを以下のように変更します:
|
|
これにより、ルートの.env
ファイルの変数が各ワークスペースのビルドプロセスに渡されます。
2. 環境変数共有パッケージの作成
大規模なプロジェクトでは、内部パッケージとして環境変数を集中管理することも検討できます:
|
|
packages/env/index.ts
の例:
|
|
このパッケージを各アプリから使用することで、型安全な環境変数アクセスが可能になります。
3. Next.jsとの連携
Next.jsの環境変数機能とTurborepoを組み合わせる場合、以下の点に注意が必要です:
- クライアントサイドで使用する変数は
NEXT_PUBLIC_
接頭辞が必要 - ビルド時に使用する変数は
turbo.json
のenv
またはpassThroughEnv
に明示的に追加 - 開発時と本番時で異なる挙動が必要な変数は
.env.development
と.env.production
で管理
ワークスペースレベルでの環境変数管理
Turborepoの強力な機能の一つに、各ワークスペース(アプリやパッケージ)ごとに個別のturbo.json
を定義できる点があります。これにより、特定のアプリだけに必要な環境変数設定を効率的に管理できます。
ワークスペース固有のturbo.json
|
|
ワークスペースでのenv/passThroughEnvの設定 (Turborepo 2.0)
各ワークスペースのturbo.json
では、env
とpassThroughEnv
を個別に設定できます:
|
|
|
|
アプリごとに設定すべき理由
アプリごとにturbo.json
で環境変数を設定するメリットは以下の通りです:
-
キャッシュの効率化
- アプリAの環境変数が変更されても、アプリBのキャッシュは無効化されません
- これにより、ビルド時間が大幅に削減されます
-
設定の明確化
- どの環境変数がどのアプリに必要なのかが明確になります
- コードベースが大きくなっても管理しやすい構造を維持できます
-
責任の分離
- 各アプリのチームが自分たちの環境変数を管理できます
- 他のアプリへの影響を心配せずに変更できます
重要なポイント
extends: ["//"]
- このコマンドでルートのturbo.json
の設定を継承します- 設定のマージ - ワークスペースの設定はルートの設定とマージされます。つまり、両方の
env
/passThroughEnv
配列に定義された変数が有効になります - スコープの限定 -
web
アプリの環境変数はadmin
アプリのキャッシュに影響しません
実際のユースケース
開発環境と本番環境での切り替え
|
|
|
|
このようにすることで、環境に応じた設定を維持しながらも、不要な再ビルドを避けることができます。
機密情報の扱い
APIキーなどの機密情報は、.env.local
ファイルに保存し、バージョン管理から除外します:
|
|
CI/CD環境では、環境変数をVercelやGitHub Actionsで設定することでセキュリティを確保します。
まとめ
Turborepoにおける環境変数管理は、以下のポイントを押さえることで効率的に行えます:
env
とpassThroughEnv
を適切に使い分けるglobalDependencies
とglobalEnv
の違いを理解し、適切に使用する- アプリ固有の変数はワークスペースレベルの
turbo.json
で管理する - 本当にグローバルな性質を持つ変数だけを
globalEnv
に指定する - 必要に応じて
dotenv-cli
や専用パッケージを活用する - 機密情報は
.env.local
で管理し、バージョン管理から除外する - Turborepo 2.0では
pipeline
からtasks
に変更され、globalEnv
が導入されたことに注意する
これらのテクニックを活用することで、複数のNext.jsアプリを含むTurborepoプロジェクトでも、環境変数を効率的に管理できるようになります。
モノレポの規模が大きくなるほど、環境変数の管理は複雑になりがちですが、Turborepoの機能を理解して活用することで、開発体験を向上させつつ、ビルド時間も短縮できます。ぜひ、自分のプロジェクトに合った環境変数管理の戦略を見つけてください。