# 通知設計書 31-コンパイル警告通知

## 概要

本ドキュメントは、Next.js開発サーバーにおけるコンパイル警告通知の設計について記載する。コンパイル警告が発生した際にサーバーサイドのコンソールへ警告メッセージを出力する通知機能である。

### 本通知の処理概要

コンパイル警告通知は、開発サーバーでのコード変更に伴うコンパイル処理において、致命的でないが開発者が認識すべき警告が検出された場合にコンソールへ出力する機能である。

**業務上の目的・背景**：開発中のコード品質を維持するため、コンパイル時に検出された非致命的な問題（非推奨のAPI使用、型の不一致の可能性、パフォーマンス上の懸念など）を開発者に即座にフィードバックする。警告を無視し続けると将来的にエラーとなる可能性があるため、早期の対処を促すことが目的である。

**通知の送信タイミング**：開発サーバーのコンパイル処理が完了し、`OutputState`の`warnings`配列にメッセージが存在する場合に送信される。コンパイルは、ファイル変更の検出、初回ビルド、またはページへのアクセスによるオンデマンドコンパイルのタイミングで実行される。

**通知の受信者**：開発サーバーを起動しているターミナルを監視している開発者。コンソール出力（`console.warn`）を通じてメッセージが表示される。

**通知内容の概要**：コンパイラ（Webpack/Turbopack）が検出した警告メッセージの全文が出力される。複数の警告がある場合は改行2つ（`\n\n`）で結合されて1つのログエントリとして出力される。メッセージの先頭には黄色の警告アイコン（`⚠`）プレフィックスが付与される。

**期待されるアクション**：開発者は警告内容を確認し、該当するコードの修正を検討する。警告が意図的なものであれば無視してもよいが、将来のバージョンで問題となる可能性がある場合は早期に対処することが推奨される。

## 通知種別

コンソール出力（サーバーサイドターミナル）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（storeサブスクリプション内で即時出力） |
| 優先度 | 中 |
| リトライ | 無し（コンソール出力のため） |

### 送信先決定ロジック

開発サーバープロセスの標準エラー出力（`console.warn`）に直接出力される。送信先の動的な決定ロジックは存在しない。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr（console.warn） |
| プレフィックス | `⚠`（黄色太字） |
| 形式 | テキスト |

### 本文テンプレート

```
⚠ {警告メッセージ1}

{警告メッセージ2}

{警告メッセージN}
```

### 添付ファイル

該当なし（コンソール出力のため添付ファイルは存在しない）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| warnings | コンパイル警告メッセージの配列 | OutputState.warnings | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| storeサブスクリプション | OutputState変更 | `state.warnings`が非null | storeの状態が更新され、warningsフィールドに警告メッセージが存在する場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| logging === false | `state.logging`がfalseの場合、すべてのログ出力が抑止される |
| state.bootstrap === true | ブートストラップ中は出力されない |
| state.loading === true | コンパイル中（loading状態）では警告は出力されない |
| state.errors !== null | エラーが存在する場合はエラー出力が優先され、警告は出力されない |
| stateが変更されていない | `hasStoreChanged()`がfalseを返す場合、重複出力を防ぐ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[OutputState変更] --> B{logging有効?}
    B -->|No| Z[出力なし]
    B -->|Yes| C{state変更あり?}
    C -->|No| Z
    C -->|Yes| D{bootstrap中?}
    D -->|Yes| Z
    D -->|No| E{loading中?}
    E -->|Yes| Z
    E -->|No| F{errors存在?}
    F -->|Yes| G[エラー出力（別処理）]
    F -->|No| H{warnings存在?}
    H -->|No| I[正常完了処理]
    H -->|Yes| J[Log.warn で警告出力]
    J --> K[flushAllTraces]
    K --> L[teardownTraceSubscriber]
    L --> M[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースは使用しない。インメモリのstoreのみを参照する）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| コンソール出力失敗 | 標準出力がリダイレクトされている等の理由で出力に失敗 | Node.jsランタイムレベルのエラーとなり、通常は発生しない |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（開発サーバー稼働中は常時出力可能）

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

- コンソール出力はローカル開発環境のみで使用されるため、個人情報漏洩のリスクは低い
- 警告メッセージにはファイルパスが含まれる場合があるが、ローカル環境のパスであるため問題はない
- `hasStoreChanged()`による重複抑止により、不要な大量出力を防止している

## 備考

- 警告メッセージは複数ある場合、`\n\n`で結合されて1つの`Log.warn()`呼び出しで出力される
- `Log.warn()`は内部で`console.warn()`を使用し、プレフィックスとして黄色太字の`⚠`を付与する
- 警告出力後、`flushAllTraces()`と`teardownTraceSubscriber()`が呼ばれ、トレースデータがフラッシュされる

---

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

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

### 推奨読解順序

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

まず、コンパイル状態を管理するデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | store.ts | `packages/next/src/build/output/store.ts` | `OutputState`型定義（8-34行目）。`bootstrap`, `loading`, `errors`, `warnings`, `typeChecking`の各状態を理解する |

**読解のコツ**: `OutputState`はUnion型で定義されており、`bootstrap: true`の場合と`bootstrap: false`の場合で異なるフィールドを持つ。さらに`bootstrap: false`の中で`loading: true`と`loading: false`の2つのバリアントがある。

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

処理の起点となるstoreサブスクリプションを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | store.ts | `packages/next/src/build/output/store.ts` | `store.subscribe()`（84行目）がエントリーポイント。状態変更のたびにコールバックが実行される |

**主要処理フロー**:
1. **84行目**: `store.subscribe((state) => { ... })` でstateの変更を監視
2. **91行目**: `!logging`ならreturn（出力抑止）
3. **95行目**: `!hasStoreChanged(state)`ならreturn（変更なし）
4. **99行目**: `state.bootstrap`ならreturn
5. **103行目**: `state.loading`なら読み込み処理へ
6. **133行目**: `state.errors`ならエラー出力へ
7. **159-164行目**: `state.warnings`がある場合、`Log.warn()`で警告出力

#### Step 3: ログ出力ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | log.ts | `packages/next/src/build/output/log.ts` | `warn()`関数（57-59行目）が実際のコンソール出力を行う。`prefixedLog()`（20-43行目）で`⚠`プレフィックスを付与 |

**主要処理フロー**:
- **57行目**: `warn()`は`prefixedLog('warn', ...message)`を呼び出す
- **20行目**: `prefixedLog()`は`console[consoleMethod](prefix, ...message)`で出力
- **7行目**: warnプレフィックスは`yellow(bold('⚠'))`

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

```
store.subscribe() [store.ts:84]
    |
    +-- hasStoreChanged() [store.ts:62]
    |
    +-- Log.warn() [log.ts:57]
    |      +-- prefixedLog('warn', ...) [log.ts:20]
    |             +-- console.warn() [Node.js built-in]
    |
    +-- flushAllTraces() [trace module]
    +-- teardownTraceSubscriber() [swc module]
```

### データフロー図

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

コンパイラ                store.subscribe()              コンソール
(Webpack/Turbopack)  -->  state.warnings チェック   -->  console.warn()
                          Log.warn(join('\n\n'))         (⚠ プレフィックス付き)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| store.ts | `packages/next/src/build/output/store.ts` | ソース | OutputStateの定義とstoreサブスクリプション。警告出力の判定ロジック |
| log.ts | `packages/next/src/build/output/log.ts` | ソース | コンソール出力ユーティリティ。プレフィックス付きログ出力 |
