# 機能設計書 83-環境変数

## 概要

本ドキュメントは、Next.jsにおける環境変数の読み込み・公開制御・ビルド時インライン化に関する機能設計書である。`.env`ファイルによる環境変数の管理と、`NEXT_PUBLIC_`プレフィックスによるクライアント/サーバー公開制御を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Webアプリケーション開発において、API鍵・データベース接続情報・機能フラグなどの環境依存の設定値を安全に管理する必要がある。Next.jsは`.env`ファイルによる階層的な環境変数管理と、クライアントサイドへの意図しない秘密情報漏洩を防止するプレフィックス制御機能を提供する。

**機能の利用シーン**：`next dev`、`next build`、`next start`の各コマンド実行時に環境変数が読み込まれる。開発者はAPIエンドポイント、認証情報、機能フラグなどを`.env`ファイルで管理し、`NEXT_PUBLIC_`プレフィックスでクライアントサイドに公開する変数を制御する。

**主要な処理内容**：
1. `.env`、`.env.local`、`.env.development`、`.env.production`等のファイルから環境変数を読み込み
2. `NEXT_PUBLIC_`プレフィックス付き変数のクライアントサイドバンドルへのインライン化
3. `next.config.js`の`env`設定による追加環境変数の定義
4. `NODE_*`、`__*`プレフィックスの変数キーの使用禁止チェック
5. デプロイメントIDの静的環境変数としての注入

**関連システム・外部連携**：`@next/env`パッケージ（.envファイル読み込み）、Webpack/Turbopack DefinePlugin（ビルド時インライン化）

**権限による制御**：`NEXT_PUBLIC_`プレフィックスのない環境変数はサーバーサイドのみでアクセス可能。クライアントサイドコードでは`process.env.NEXT_PUBLIC_*`のみ参照可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面を持たない内部処理機構である |

## 機能種別

設定管理 / データ変換 / セキュリティ制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| config | NextConfigComplete / NextConfigRuntime | Yes | Next.js設定オブジェクト | - |
| deploymentId | string | No | デプロイメント識別子 | - |

### 入力データソース

- `.env` ファイル群（`.env`、`.env.local`、`.env.development`、`.env.production`等）
- `next.config.js` の `env` 設定オブジェクト
- `process.env` のランタイム環境変数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| defineEnv | Record<string, string> | `process.env.KEY` 形式のキーと値のマッピング |
| NEXT_PUBLIC_* | string | クライアントサイドバンドルにインライン化される公開環境変数 |

### 出力先

- Webpack/Turbopack DefinePlugin（ビルド時のコード置換）
- `process.env`（ランタイム環境変数）

## 処理フロー

### 処理シーケンス

```
1. @next/envによる.envファイル読み込み
   └─ loadEnvConfig(dir, isDev)
2. NEXT_PUBLIC_プレフィックス変数の収集
   └─ getNextPublicEnvironmentVariables()
3. next.config.jsのenv設定値の収集
   └─ getNextConfigEnv(config)
   └─ NODE_*、__*プレフィックスの禁止チェック
4. 静的環境変数のマージ
   └─ getStaticEnv(config, deploymentId)
5. ビルド時のDefinePluginへの注入
   └─ process.env.KEYとして文字列リテラルに置換
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[.envファイル読み込み]
    B --> C[process.envに環境変数設定]
    C --> D[NEXT_PUBLIC_変数を収集]
    D --> E[next.config.js env設定を収集]
    E --> F{禁止キー?}
    F -->|Yes| G[エラースロー]
    F -->|No| H[静的環境変数マージ]
    H --> I[DefinePluginに注入]
    I --> J[ビルド時にprocess.env.KEYを文字列リテラルに置換]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-83-01 | 公開プレフィックス制御 | `NEXT_PUBLIC_`プレフィックス付き変数のみクライアントサイドに公開 | 全環境 |
| BR-83-02 | 禁止キー制御 | `NODE_*`、`__*`、`NEXT_RUNTIME`は`env`設定で使用不可 | next.config.jsのenv設定 |
| BR-83-03 | ファイル優先度 | `.env.local` > `.env.{development,production}` > `.env` の順で優先 | .envファイル読み込み時 |
| BR-83-04 | デプロイメントID | `process.env.NEXT_DEPLOYMENT_ID`が静的環境変数として自動注入される | デプロイメントID設定時 |
| BR-83-05 | ソート順序 | NEXT_PUBLIC_変数はキー名のアルファベット順にソートされる | ビルド時 |

### 計算ロジック

特になし。

## データベース操作仕様

本機能はデータベースに対する操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | `env`設定に`NODE_*`や`__*`プレフィックスのキーが含まれる | 禁止キーを削除する |
| - | Error | `NEXT_RUNTIME`キーが`env`設定に含まれる | NEXT_RUNTIMEキーを削除する |

### リトライ仕様

リトライは行わない。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

環境変数の読み込みはアプリケーション起動時に1回のみ実行される。処理は軽量でミリ秒単位で完了する。

## セキュリティ考慮事項

- `NEXT_PUBLIC_`プレフィックスのない変数はクライアントサイドバンドルに含まれず、サーバーサイドのみでアクセス可能
- `.env.local`はバージョン管理から除外すべき（.gitignoreに追加）
- 機密情報（API鍵等）には`NEXT_PUBLIC_`プレフィックスを付けてはならない

## 備考

- `@next/env`パッケージが実際の`.env`ファイル読み込みを担当する
- テスト環境では`.env.test`が使用される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | static-env.ts | `packages/next/src/lib/static-env.ts` | 環境変数処理の主要関数群の型定義を理解する |

**読解のコツ**: 環境変数はすべて`Record<string, string | undefined>`形式で扱われ、キーは`process.env.KEY`形式の文字列である。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | static-env.ts | `packages/next/src/lib/static-env.ts` | **56-66行目**: `getStaticEnv`がメインのエントリーポイント。NEXT_PUBLIC_変数、config.env変数、デプロイメントIDをマージ |

**主要処理フロー**:
1. **6-18行目**: `errorIfEnvConflicted` - 禁止キーチェック（NODE_*、__*、NEXT_RUNTIME）
2. **23-35行目**: `getNextPublicEnvironmentVariables` - NEXT_PUBLIC_プレフィックス変数の収集・ソート
3. **40-54行目**: `getNextConfigEnv` - next.config.jsのenv設定値の収集（禁止キーチェック付き）
4. **56-66行目**: `getStaticEnv` - 全環境変数のマージとNEXT_DEPLOYMENT_IDの追加

#### Step 3: .envファイル読み込みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.ts | `packages/next/src/server/config.ts` | **26行目**: `loadEnvConfig`のインポートと使用箇所。@next/envパッケージが.envファイル読み込みを担当 |

#### Step 4: ビルド時インライン化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | static-env.ts | `packages/next/src/lib/static-env.ts` | **68-82行目**: `populateStaticEnv`でprocess.envへの静的環境変数の反映 |

### プログラム呼び出し階層図

```
ビルドプロセス / サーバー起動
    |
    +-- loadEnvConfig()              # @next/envによる.envファイル読み込み
    |       +-- .env読み込み
    |       +-- .env.local読み込み
    |       +-- .env.{mode}読み込み
    |
    +-- getStaticEnv()               # 静的環境変数の収集
    |       +-- getNextPublicEnvironmentVariables()
    |       |       +-- process.envからNEXT_PUBLIC_*を収集
    |       +-- getNextConfigEnv()
    |       |       +-- config.envから変数を収集
    |       |       +-- errorIfEnvConflicted()  # 禁止キーチェック
    |       +-- NEXT_DEPLOYMENT_IDの追加
    |
    +-- populateStaticEnv()          # process.envへの反映
    |
    +-- DefinePlugin                 # Webpack/Turbopackでのインライン化
```

### データフロー図

```
[入力]                    [処理]                          [出力]

.envファイル群 ────────▶ loadEnvConfig() ───────────┐
                                                    ├──▶ process.env
process.env ──────────▶ getNextPublicEnvironmentVariables() ──┐
                                                              ├──▶ defineEnv
next.config.js env ───▶ getNextConfigEnv() ───────────────────┤
                                                              └──▶ DefinePlugin
deploymentId ─────────▶ getStaticEnv() ──────────────────────────▶ (ビルド時置換)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| static-env.ts | `packages/next/src/lib/static-env.ts` | ソース | 静的環境変数の収集・マージ・反映 |
| config.ts | `packages/next/src/server/config.ts` | ソース | loadEnvConfigの呼び出し元 |
| @next/env | `packages/next-env/` | 外部パッケージ | .envファイルの読み込みライブラリ |
| define-env.ts | `packages/next/src/build/define-env.ts` | ソース | ビルド時のDefinePlugin用環境変数定義 |
