# 通知設計書 1-ランタイム警告（warn）

## 概要

本ドキュメントは、Vue.jsランタイムにおける開発者向け警告通知（`warn`関数）の設計仕様を記述する。`packages/runtime-core/src/warning.ts`に実装されたVueの中核的な開発者通知機構であり、73ファイル以上から呼び出される最も重要な警告システムである。

### 本通知の処理概要

この通知は、開発モード（`__DEV__`）でVueの内部チェックに違反した場合に`console.warn`を通じて開発者に警告を通知する機構である。コンポーネントツリーのトレース情報を付与し、`app.config.warnHandler`が設定されていればそちらに委譲する。

**業務上の目的・背景**：Vue.jsフレームワークの利用者（開発者）がAPIの誤用、非推奨パターンの使用、型の不一致などの問題を早期に検出できるようにするために存在する。開発モードでのみ動作し、本番ビルドではツリーシェイキングにより除去されるため、パフォーマンスへの影響はない。フレームワーク内部の73以上のファイルから呼び出される中核的な通知機構であり、開発体験（DX）の向上に直結する。

**通知の送信タイミング**：Vueの内部バリデーションチェックに違反した場合に即座に発火する。具体的には、コンポーネントのプロパティ検証失敗、不正なディレクティブ使用、ライフサイクルフックの誤用、リアクティブシステムの不正操作など、フレームワークが検出できるあらゆる開発時のミスに対して発火する。`__DEV__`フラグがtrueの場合のみ実行される。

**通知の受信者**：アプリケーション開発者。ブラウザの開発者コンソール（DevTools）を通じて警告メッセージを確認する。`app.config.warnHandler`が設定されている場合は、カスタムハンドラに委譲されるため、外部ログサービスへの転送も可能。

**通知内容の概要**：`[Vue warn]: `プレフィックス付きの警告メッセージ、コンポーネントツリーのトレース情報（コンポーネント名、props情報、再帰呼び出し回数）、および追加の引数情報が含まれる。

**期待されるアクション**：開発者が警告メッセージを確認し、コードの修正を行う。コンポーネントトレースにより問題箇所の特定が容易になっている。

## 通知種別

コンソール警告（`console.warn`）/ カスタムハンドラ委譲（`app.config.warnHandler`）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中（開発時のみ動作） |
| リトライ | なし |

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

1. `app.config.warnHandler`が設定されている場合、カスタムハンドラに委譲する
2. 未設定の場合、`console.warn`でブラウザコンソールに出力する
3. 再帰呼び出しを防止するため、`isWarning`フラグでガードされている

## 通知テンプレート

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

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | N/A（コンソール出力） |
| 送信元名称 | `[Vue warn]` |
| 件名 | N/A |
| 形式 | テキスト |

### 本文テンプレート

```
[Vue warn]: {警告メッセージ} {追加引数}

  at <{コンポーネント名} {props情報}>
  at <{親コンポーネント名}>
  at <{ルートコンポーネント名(root)}>
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | N/A | N/A | コンソール出力のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| msg | 警告メッセージ本文 | 呼び出し元から渡される文字列引数 | Yes |
| args | 追加情報 | 呼び出し元から渡される可変長引数 | No |
| instance | 現在のコンポーネントインスタンス | VNodeスタックの末尾 | No |
| trace | コンポーネントツリーのトレース情報 | getComponentTrace()で生成 | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | warn()関数の呼び出し | `__DEV__` がtrue | フレームワーク内部の73以上のファイルから呼び出される |
| バリデーション | プロパティ検証失敗 | 型/値の不一致 | コンポーネントpropsの型チェック |
| バリデーション | 不正なディレクティブ使用 | 使用法の誤り | v-model、v-ifなどの誤用 |
| バリデーション | 未宣言イベントのemit | emitsオプションに未定義 | コンポーネントイベントの検証 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `__DEV__` がfalse | 本番ビルドでは全ての警告が除去される |
| `isWarning` がtrue | 再帰呼び出し防止（警告処理中の再警告を抑止） |
| `__TEST__` がtrue | テスト実行中はトレース情報の出力が抑止される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[warn関数呼び出し] --> B{isWarningフラグチェック}
    B -->|true: 再帰呼び出し| Z[即座にreturn]
    B -->|false| C[isWarning = true]
    C --> D[pauseTracking: リアクティブ追跡を一時停止]
    D --> E[VNodeスタックからインスタンスを取得]
    E --> F[getComponentTrace: コンポーネントトレース生成]
    F --> G{app.config.warnHandler<br>が設定されているか}
    G -->|設定あり| H[callWithErrorHandling経由で<br>warnHandlerを呼び出し]
    G -->|未設定| I[console.warnで出力]
    I --> J{トレース情報があるか<br>かつテスト中でないか}
    J -->|あり| K[formatTrace: トレース情報を整形して付与]
    J -->|なし| L[メッセージのみ出力]
    K --> M[resetTracking: リアクティブ追跡を再開]
    L --> M
    H --> M
    M --> N[isWarning = false]
    N --> O[終了]
    Z --> O
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | N/A | データベースは使用しない。インメモリのVNodeスタックを参照する |

### テーブル別参照項目詳細

本通知はデータベースを使用しない。以下のインメモリデータ構造を参照する。

| 参照データ | 用途 | 取得方法 |
|-----------|------|---------|
| stack (VNode[]) | 現在のコンポーネントコンテキスト | モジュールスコープの配列 |
| instance.appContext.config.warnHandler | カスタム警告ハンドラ | コンポーネントインスタンスから取得 |
| vnode.component.parent | 親コンポーネントへの参照 | VNodeツリーを辿る |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| N/A | N/A | データベースの更新は行わない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 再帰呼び出し | warnHandler内部でwarnが呼ばれた場合 | isWarningフラグで防止し、即座にreturn |
| warnHandlerのエラー | カスタムハンドラ内でエラー発生 | callWithErrorHandling経由で安全に呼び出し、エラーはerrorHandlingに委譲 |
| リアクティブ追跡の干渉 | 警告処理中にリアクティブプロパティが読み取られる | pauseTracking/resetTrackingで一時停止 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし。開発モードで実行中は常時有効。

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

- 本番ビルド（`__DEV__` = false）ではツリーシェイキングにより完全に除去されるため、本番環境への影響なし
- warnHandlerに機密情報が渡される可能性があるため、外部サービスへの転送時は注意が必要
- コンポーネントのprops情報がトレースに含まれるため、開発コンソールに表示される

## 備考

- Vue 3.xの中核的な開発者通知機構であり、73ファイル以上から呼び出される
- `pushWarningContext`/`popWarningContext`によりコンポーネントコンテキストが管理される
- `assertNumber`ヘルパー関数も同ファイルに定義されており、数値バリデーション用の警告を提供する
- `formatProps`は最大3つのpropsまでを表示し、それ以上は`...`で省略する
- Ref型のpropsは`Ref<値>`形式で表示される

---

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

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

### 推奨読解順序

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

まず、警告システムで使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | warning.ts | `packages/runtime-core/src/warning.ts` | L12-23: ComponentVNode型、TraceEntry型、ComponentTraceStack型の定義を理解する |
| 1-2 | component.ts | `packages/runtime-core/src/component.ts` | ComponentInternalInstance型、ConcreteComponent型の構造を理解する |
| 1-3 | apiCreateApp.ts | `packages/runtime-core/src/apiCreateApp.ts` | AppConfig型のwarnHandler定義を理解する |

**読解のコツ**: TypeScriptの型定義を先に把握することで、関数のシグネチャや引数の意味が明確になる。

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

処理の起点となる`warn`関数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | warning.ts | `packages/runtime-core/src/warning.ts` | L35-79: warn関数本体。再帰防止、トラッキング一時停止、warnHandler委譲、console.warn出力の流れ |

**主要処理フロー**:
1. **L36**: `isWarning`フラグによる再帰呼び出し防止チェック
2. **L41**: `pauseTracking()`でリアクティブ追跡を一時停止
3. **L43**: VNodeスタックから現在のコンポーネントインスタンスを取得
4. **L44**: `appWarnHandler`の有無を確認
5. **L47-63**: warnHandlerが設定されている場合、callWithErrorHandling経由で委譲
6. **L64-75**: 未設定の場合、`[Vue warn]: `プレフィックスを付けてconsole.warn出力
7. **L77-78**: `resetTracking()`でリアクティブ追跡を再開し、isWarningをfalseに戻す

#### Step 3: コンポーネントトレース生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | warning.ts | `packages/runtime-core/src/warning.ts` | L81-108: getComponentTrace関数。親コンポーネントを辿って再帰的にトレース情報を構築する |

**主要処理フロー**:
- **L82**: VNodeスタックの末尾から開始
- **L92-105**: parentポインタを辿りながら、ComponentTraceStackを構築。同一VNodeの再帰呼び出しはrecurseCountでカウント

#### Step 4: トレース情報のフォーマットを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | warning.ts | `packages/runtime-core/src/warning.ts` | L111-167: formatTrace、formatTraceEntry、formatProps、formatProp関数群 |

**主要処理フロー**:
- **L119-132**: formatTraceEntry - コンポーネント名、ルート判定、props情報の整形
- **L134-143**: formatProps - 最大3つのpropsを表示、超過分は`...`で省略
- **L148-167**: formatProp - 値の型に応じた表示形式（String、Number、Ref、Function等）

#### Step 5: 警告コンテキスト管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | warning.ts | `packages/runtime-core/src/warning.ts` | L16, L25-31: stackとpush/popWarningContext関数 |
| 5-2 | errorHandling.ts | `packages/runtime-core/src/errorHandling.ts` | L70-80: callWithErrorHandling - warnHandlerの安全な呼び出しラッパー |

**主要処理フロー**:
- **L16**: モジュールスコープの`stack`配列でVNodeコンテキストを管理
- **L25-27**: `pushWarningContext` - レンダリング開始時にVNodeをスタックにプッシュ
- **L29-31**: `popWarningContext` - レンダリング完了時にスタックからポップ

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

```
warn(msg, ...args)                    [warning.ts:35]
    |
    +-- pauseTracking()                [reactivity/effect.ts:514]
    |
    +-- getComponentTrace()            [warning.ts:81]
    |       |
    |       +-- component.parent       [VNodeツリー走査]
    |
    +-- [warnHandler設定時]
    |       |
    |       +-- callWithErrorHandling() [errorHandling.ts:70]
    |               |
    |               +-- appWarnHandler() [ユーザー定義ハンドラ]
    |
    +-- [warnHandler未設定時]
    |       |
    |       +-- formatTrace()           [warning.ts:111]
    |       |       |
    |       |       +-- formatTraceEntry() [warning.ts:119]
    |       |               |
    |       |               +-- formatComponentName() [component.ts]
    |       |               +-- formatProps()  [warning.ts:134]
    |       |                       |
    |       |                       +-- formatProp() [warning.ts:148]
    |       |
    |       +-- console.warn()
    |
    +-- resetTracking()                [reactivity/effect.ts:530]
```

### データフロー図

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

msg (string)          +-- warn()                        +-- console.warn()
  |                   |     |                           |     "[Vue warn]: ..."
args (...any[])  ---->|     +-- isWarningチェック   ---->|
  |                   |     +-- pauseTracking()         +-- warnHandler()
stack (VNode[])  ---->|     +-- getComponentTrace()          カスタム処理
  |                   |     +-- formatTrace()           |
  |                   |     +-- resetTracking()         +-- トレース情報
  |                   +--                                    "at <ComponentName>"
appWarnHandler   ---->
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| warning.ts | `packages/runtime-core/src/warning.ts` | ソース | warn関数本体、トレース生成、フォーマット処理 |
| errorHandling.ts | `packages/runtime-core/src/errorHandling.ts` | ソース | callWithErrorHandling（warnHandler安全呼び出し） |
| component.ts | `packages/runtime-core/src/component.ts` | ソース | ComponentInternalInstance型、formatComponentName関数 |
| apiCreateApp.ts | `packages/runtime-core/src/apiCreateApp.ts` | ソース | AppConfig.warnHandler定義 |
| effect.ts | `packages/reactivity/src/effect.ts` | ソース | pauseTracking/resetTracking関数 |
