# 機能設計書 70-@vue/compat

## 概要

本ドキュメントは、Vue 3の`@vue/compat`パッケージの設計仕様を記述する。このパッケージはVue 2からVue 3への移行をサポートする互換性レイヤーであり、Vue 2のAPI互換動作を提供しつつ、段階的な移行を可能にする。

### 本機能の処理概要

`@vue/compat`（vue-compat）は、Vue 3のランタイムにVue 2の互換APIを追加する移行ビルドである。Vue 2の廃止されたAPIや変更されたAPIの互換動作を提供し、各APIごとに個別に互換モードの有効/無効を切り替えることで、段階的にVue 3へ移行できるようにする。

**業務上の目的・背景**：Vue 2からVue 3への移行は、多数の破壊的変更（Global API、コンポーネントAPI、テンプレート構文、レンダリング関数等）を伴う。大規模アプリケーションでは一括移行が困難であるため、`@vue/compat`は互換性レイヤーとして動作し、Vue 2のコードをVue 3ランタイム上で実行できるようにする。各廃止APIの使用時には警告メッセージが表示され、移行ガイドへのリンクが提供される。

**機能の利用シーン**：
- Vue 2アプリケーションのVue 3移行時
- Vue 2プラグイン/ライブラリのVue 3互換性テスト
- 段階的な移行プロセスの管理

**主要な処理内容**：
1. Vue 2グローバルAPI互換（Vue.extend、Vue.set、Vue.delete、Vue.observable、Vue.prototype等）
2. Vue 2コンポーネントAPI互換（$mount、$destroy、$on/$off/$once、$children、$listeners等）
3. Vue 2オプションAPI互換（data関数以外、beforeDestroy/destroyed、filters等）
4. Vue 2レンダリング関数API互換
5. Vue 2ディレクティブフック名互換
6. Vue 2トランジションクラス名互換
7. 各互換機能の個別ON/OFF設定（configureCompat()）
8. 廃止警告メッセージの表示と移行ガイドリンク

**関連システム・外部連携**：`@vue/runtime-dom`、`@vue/runtime-core`のcompat機能と連携。`@vue/compiler-dom`（フルビルド時）。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ランタイム互換レイヤー。直接的な画面関連なし |

## 機能種別

互換性レイヤー（Vue 2 -> Vue 3 移行支援）

## 入力仕様

### 入力パラメータ

#### configureCompat()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| config | `CompatConfig` | Yes | 互換設定オブジェクト。MODEと各DeprecationTypes | MODEは2または3 |

#### CompatConfig型

| プロパティ | 型 | 説明 |
|-----------|-----|------|
| MODE | `2 \| 3 \| ((comp) => 2 \| 3)` | デフォルトモード。2=Vue 2互換、3=Vue 3動作 |
| [DeprecationTypes] | `boolean \| 'suppress-warning'` | 個別機能の有効/無効/警告抑制 |

### 入力データソース

アプリケーションの初期化コードからconfigureCompat()で設定。コンポーネント単位でcompatConfigオプションで上書き可能。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CompatVueコンストラクタ | `CompatVue` | Vue 2互換のグローバルVueコンストラクタ |
| 廃止警告メッセージ | `string` | コンソールに出力される警告メッセージ |

### 出力先

- Vue 2互換のグローバルVueオブジェクトとしてエクスポート
- 廃止警告はconsole.warn経由で出力

## 処理フロー

### 処理シーケンス

```
1. @vue/compat パッケージ読み込み
   └─ createCompatVue()でVue 2互換のVueコンストラクタを生成
2. wrappedCreateApp()
   └─ 互換モード有効時にTransition/TransitionGroup/KeepAlive/v-show/v-modelを登録
3. createCompatVue()
   ├─ singletonApp（シングルトンアプリ）を生成
   ├─ Vueコンストラクタ関数を定義
   │      └─ new Vue(options) → createCompatApp(options)
   ├─ Vue.version = "2.6.14-compat:${VERSION}"
   ├─ Vue.config = singletonApp.config
   ├─ Vue.use() / Vue.mixin() / Vue.component() / Vue.directive()
   ├─ Vue.extend() → extendCtor()
   ├─ Vue.set() / Vue.delete() / Vue.observable()
   ├─ Vue.filter()
   ├─ Vue.util（内部API）
   └─ Vue.configureCompat = configureCompat
4. 各Vue 2 API使用時
   └─ assertCompatEnabled() / softAssertCompatEnabled()で互換チェック
      ├─ isCompatEnabled()でモードに基づき互換動作の有効/無効を判定
      └─ warnDeprecation()で廃止警告を出力
```

### フローチャート

```mermaid
flowchart TD
    A[import Vue from '@vue/compat'] --> B[createCompatVue]
    B --> C[singletonApp生成]
    C --> D[Vueコンストラクタ定義]
    D --> E[Vue 2互換APIの登録]
    E --> F{Vue 2 API呼び出し}
    F --> G[isCompatEnabled チェック]
    G --> H{互換有効?}
    H -->|Yes| I[互換動作実行]
    H -->|No| J[Error throw / Vue 3動作]
    I --> K[warnDeprecation 警告表示]
    K --> L[移行ガイドリンク表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-70-01 | MODEデフォルト | デフォルトMODEは2（Vue 2互換）。テストモードではMODE 3 | 初期設定 |
| BR-70-02 | MODE 2動作 | MODE 2では各DeprecationType がfalseに設定されない限り互換動作が有効 | MODE=2 |
| BR-70-03 | MODE 3動作 | MODE 3では各DeprecationTypeがtrueまたはsuppress-warningに設定されない限り互換動作が無効 | MODE=3 |
| BR-70-04 | コンポーネント単位設定 | compatConfigオプションでコンポーネント単位の互換設定が可能（グローバル設定を上書き） | コンポーネントにcompatConfig指定時 |
| BR-70-05 | 警告の重複抑制 | 同一コンポーネント型で同一警告が既に表示されている場合、警告カウントのみ表示 | 2回目以降の同一警告 |
| BR-70-06 | ビルトインコンポーネント除外 | __isBuiltInフラグを持つコンポーネントは互換チェックをスキップ | ビルトインコンポーネント |
| BR-70-07 | バージョン文字列 | Vue.versionは "2.6.14-compat:{実際のVue 3バージョン}" 形式 | 常時 |

### 計算ロジック

互換有効判定ロジック（`isCompatEnabled()`）:
```
mode = getCompatConfigForKey('MODE', instance) || 2
val = getCompatConfigForKey(key, instance)

if (mode === 2) → val !== false なら互換有効
if (mode === 3) → val === true || val === 'suppress-warning' なら互換有効
```

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | 互換無効のAPIを呼び出した場合 | assertCompatEnabled()がError throw |
| - | 警告 | 互換有効のAPIを呼び出した場合（開発モード） | warnDeprecation()で移行ガイドリンク付き警告 |
| - | 警告 | 無効なCompatConfig キーを指定した場合 | "Invalid deprecation config" 警告 |
| - | 警告 | コンパイラ固有のキーをランタイムオンリービルドで使用した場合 | "Deprecation config is compiler-specific" 警告 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 互換レイヤーのオーバーヘッドはisCompatEnabled()チェックのコスト（globalConfigのルックアップ）
- プロダクションビルドでは__DEV__ガードにより警告出力コードが除去される
- instanceWarned/warnCountで警告の重複を抑制し、コンソール出力を最小化

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

- フルビルド（index.ts）ではin-DOMテンプレートの動的コンパイルが可能であるため、ユーザーデータを含むテンプレートのコンパイルはXSSリスクがある（コード内コメント: `__UNSAFE__`）
- Vue.utilは内部APIであり、サードパーティプラグインが使用する場合はセキュリティリスクの可能性がある

## 備考

- 全37種類のDeprecationTypes（廃止区分）が定義されており、各区分ごとにメッセージと移行ガイドリンクが提供される
- フルビルド（`index.ts`）はランタイム+コンパイラを含み、ランタイムビルド（`runtime.ts`）はランタイムのみ
- ESMバンドラー用ビルド（`esm-index.ts`）、ESMブラウザ用ビルド等、複数のビルドバリアントが提供される
- Vue.extendはextendCtorとして実装され、WeakMapでキャッシュが管理される
- defineReactive()はVue 2の互換性のために提供される簡易的なリアクティブ定義関数

---

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

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

### 推奨読解順序

#### Step 1: パッケージ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | esm-index.ts | `packages/vue-compat/src/esm-index.ts` | ESMエントリーポイント。createCompatVue()でVueコンストラクタ生成、configureCompatのエクスポート |
| 1-2 | index.ts | `packages/vue-compat/src/index.ts` | フルビルドエントリーポイント。コンパイラ込みのVueコンストラクタ（1-112行目） |
| 1-3 | runtime.ts | `packages/vue-compat/src/runtime.ts` | ランタイムのみビルド。コンパイラなし（1-23行目） |

**読解のコツ**: vue-compatは複数のビルドバリアントを持つ。index.ts（フル）ではcompileToFunction()を含み、runtime.ts（ランタイム）ではcompile()にエラーメッセージを設定する。

#### Step 2: CompatVue生成ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | createCompatVue.ts | `packages/vue-compat/src/createCompatVue.ts` | wrappedCreateApp()（23-39行目）: 互換モード時にビルトインコンポーネント/ディレクティブを登録 |
| 2-2 | createCompatVue.ts | `packages/vue-compat/src/createCompatVue.ts` | createCompatVue()（41-45行目）: compatUtils.createCompatVue()を呼び出し、runtimeDomの全APIを拡張 |

#### Step 3: グローバルAPI互換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | global.ts | `packages/runtime-core/src/compat/global.ts` | CompatVue型定義（67-134行目）: Vue 2互換のグローバルAPI型定義 |
| 3-2 | global.ts | `packages/runtime-core/src/compat/global.ts` | createCompatVue()（143-330行目）: シングルトンApp、Vueコンストラクタ、extend/set/delete/observable/filter/util等のVue 2 API実装 |
| 3-3 | global.ts | `packages/runtime-core/src/compat/global.ts` | installAppCompatProperties()（332-350行目）: アプリケーションに互換性プロパティを追加 |
| 3-4 | global.ts | `packages/runtime-core/src/compat/global.ts` | installCompatMount()（452-603行目）: $mount/$destroy互換、DOM内テンプレートの解決 |

**主要処理フロー**:
- **149-153行目**: Vueコンストラクタ関数定義。new Vue(options)はcreateCompatApp()を呼び出す
- **181行目**: Vue.version = "2.6.14-compat:${VERSION}"
- **184-191行目**: Vue.use(): プラグインのinstall関数またはプラグイン関数自体を呼び出す
- **225-280行目**: Vue.extend(): extendCtor関数。SubVue作成、オプションマージ、WeakMapキャッシュ
- **284-297行目**: Vue.set/delete/observable: Vue 2 APIの互換実装

#### Step 4: 互換設定管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | compatConfig.ts | `packages/runtime-core/src/compat/compatConfig.ts` | DeprecationTypes enum（13-67行目）: 37種類の廃止区分 |
| 4-2 | compatConfig.ts | `packages/runtime-core/src/compat/compatConfig.ts` | deprecationData（74-426行目）: 各区分のメッセージと移行ガイドリンク |
| 4-3 | compatConfig.ts | `packages/runtime-core/src/compat/compatConfig.ts` | configureCompat()（505-510行目）: グローバル互換設定 |
| 4-4 | compatConfig.ts | `packages/runtime-core/src/compat/compatConfig.ts` | isCompatEnabled()（566-588行目）: 互換有効判定ロジック |
| 4-5 | compatConfig.ts | `packages/runtime-core/src/compat/compatConfig.ts` | warnDeprecation()（438-493行目）: 廃止警告出力（重複抑制付き） |

**主要処理フロー**:
- **501-503行目**: globalCompatConfig.MODE = 2（デフォルト）
- **566-588行目**: isCompatEnabled: mode=2ならval!==false、mode=3ならval===true|suppress-warning
- **438-493行目**: warnDeprecation: instanceWarned/warnCountで重複抑制。移行ガイドリンク付き警告

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

```
@vue/compat パッケージ
    │
    ├─ createCompatVue()
    │      │
    │      ├─ wrappedCreateApp()
    │      │      └─ createApp() + ビルトイン登録
    │      │
    │      └─ compatUtils.createCompatVue() [runtime-core/compat/global.ts]
    │             │
    │             ├─ singletonApp = createApp({})
    │             ├─ Vue コンストラクタ定義
    │             │      └─ createCompatApp(options)
    │             │             ├─ assertCompatEnabled(GLOBAL_MOUNT)
    │             │             └─ createApp(options) → vm
    │             │
    │             ├─ Vue.extend = extendCtor()
    │             ├─ Vue.set / Vue.delete / Vue.observable
    │             ├─ Vue.filter
    │             └─ Vue.configureCompat
    │
    ├─ configureCompat(config) [runtime-core/compat/compatConfig.ts]
    │      └─ extend(globalCompatConfig, config)
    │
    └─ isCompatEnabled(key, instance) [runtime-core/compat/compatConfig.ts]
           ├─ getCompatConfigForKey('MODE', instance)
           ├─ getCompatConfigForKey(key, instance)
           └─ mode判定 → boolean返却
```

### データフロー図

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

configureCompat({        globalCompatConfig に設定をマージ     isCompatEnabled()
  MODE: 2,               │                                    で互換動作を判定
  GLOBAL_MOUNT: true      │
}) ──────────────────────▶ extend(globalCompatConfig, config)


new Vue(options) ────────▶ createCompatApp(options)
                                 │
                                 ├─ assertCompatEnabled(GLOBAL_MOUNT)
                                 │      └─ isCompatEnabled() → 警告 or Error
                                 │
                                 ├─ createApp(options)
                                 │
                                 └─ installCompatMount(app) ──▶ vm.$mount / vm.$destroy
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| createCompatVue.ts | `packages/vue-compat/src/createCompatVue.ts` | ソース | createCompatVue()とwrappedCreateApp()の定義 |
| index.ts | `packages/vue-compat/src/index.ts` | ソース | フルビルドエントリーポイント（コンパイラ込み） |
| runtime.ts | `packages/vue-compat/src/runtime.ts` | ソース | ランタイムのみビルドエントリーポイント |
| esm-index.ts | `packages/vue-compat/src/esm-index.ts` | ソース | ESMバンドラー向けエントリーポイント |
| esm-runtime.ts | `packages/vue-compat/src/esm-runtime.ts` | ソース | ESMランタイムビルドエントリーポイント |
| dev.ts | `packages/vue-compat/src/dev.ts` | ソース | 開発モード初期化 |
| global.ts | `packages/runtime-core/src/compat/global.ts` | ソース | CompatVue型、createCompatVue()実装、installAppCompatProperties() |
| compatConfig.ts | `packages/runtime-core/src/compat/compatConfig.ts` | ソース | DeprecationTypes、deprecationData、configureCompat()、isCompatEnabled()、warnDeprecation() |
| instance.ts | `packages/runtime-core/src/compat/instance.ts` | ソース | インスタンスレベルの互換API |
| renderFn.ts | `packages/runtime-core/src/compat/renderFn.ts` | ソース | レンダリング関数の互換処理 |
| customDirective.ts | `packages/runtime-core/src/compat/customDirective.ts` | ソース | カスタムディレクティブフック名の互換処理 |
| componentAsync.ts | `packages/runtime-core/src/compat/componentAsync.ts` | ソース | 非同期コンポーネントの互換処理 |
| componentFunctional.ts | `packages/runtime-core/src/compat/componentFunctional.ts` | ソース | 関数型コンポーネントの互換処理 |
| componentVModel.ts | `packages/runtime-core/src/compat/componentVModel.ts` | ソース | v-modelの互換処理 |
| instanceEventEmitter.ts | `packages/runtime-core/src/compat/instanceEventEmitter.ts` | ソース | $on/$off/$onceの互換処理 |
| instanceChildren.ts | `packages/runtime-core/src/compat/instanceChildren.ts` | ソース | $childrenの互換処理 |
| instanceListeners.ts | `packages/runtime-core/src/compat/instanceListeners.ts` | ソース | $listenersの互換処理 |
| globalConfig.ts | `packages/runtime-core/src/compat/globalConfig.ts` | ソース | グローバル設定の互換処理 |
| data.ts | `packages/runtime-core/src/compat/data.ts` | ソース | dataオプションの互換処理 |
| props.ts | `packages/runtime-core/src/compat/props.ts` | ソース | propsデフォルト値のthis参照互換 |
| attrsFallthrough.ts | `packages/runtime-core/src/compat/attrsFallthrough.ts` | ソース | 属性フォールスルーの互換処理 |
| renderHelpers.ts | `packages/runtime-core/src/compat/renderHelpers.ts` | ソース | レンダリングヘルパーの互換処理 |
