# アーキテクチャ設計書

## 概要

本ドキュメントは、Vue.js 3 コアリポジトリ（v3.5.27）のアプリケーションアーキテクチャを記述する。Vue.js は Progressive JavaScript Framework であり、本リポジトリはそのコアランタイム・コンパイラ・リアクティビティシステムを含むモノレポ構成のフレームワークソースコードである。pnpm workspace による12パッケージのモノレポで構成され、各パッケージが明確な責務分離のもとレイヤードアーキテクチャを形成している。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図](./アーキテクチャ構成図.md) を参照。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| Babel Parser (`@babel/parser`) | ライブラリ依存 | テンプレート式・`<script>` ブロックの JavaScript/TypeScript パース |
| PostCSS (`postcss`) | ライブラリ依存 | SFC スタイルブロックのCSS変換・スコープID注入 |
| entities (`entities`) | ライブラリ依存 | HTML エンティティのデコード |
| estree-walker (`estree-walker`) | ライブラリ依存 | AST トラバーサル |
| source-map-js (`source-map-js`) | ライブラリ依存 | ソースマップ生成 |
| magic-string (`magic-string`) | ライブラリ依存 | 文字列操作によるコード変換 |
| csstype (`csstype`) | 型定義 | CSS プロパティの TypeScript 型定義 |

## レイヤー構成

### アーキテクチャスタイル

**レイヤードアーキテクチャ + プラットフォーム抽象化パターン**

Vue.js 3 のコアは、下位レイヤーから上位レイヤーへの一方向依存を原則とするレイヤードアーキテクチャを採用している。加えて、ランタイム層はプラットフォーム非依存なコア（`runtime-core`）とプラットフォーム固有の実装（`runtime-dom`）を分離するプラットフォーム抽象化パターンを採用している。コンパイラ層も同様に、プラットフォーム非依存なコア（`compiler-core`）とDOM固有の拡張（`compiler-dom`）に分離されている。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Foundation | 全パッケージ共通のユーティリティ・定数・型定義 | `@vue/shared` |
| Reactivity | リアクティブ状態管理（依存追跡・変更通知・算出プロパティ） | `@vue/reactivity` |
| Runtime Core | プラットフォーム非依存のコンポーネントモデル・VNode・レンダリングパイプライン・スケジューラ | `@vue/runtime-core` |
| Runtime Platform | プラットフォーム固有のレンダリング実装（DOM操作・イベント処理・ディレクティブ） | `@vue/runtime-dom`, `@vue/runtime-test` |
| Compiler Core | プラットフォーム非依存のテンプレートコンパイル（パース・変換・コード生成） | `@vue/compiler-core` |
| Compiler Platform | プラットフォーム固有のコンパイラ拡張（DOM・SSR） | `@vue/compiler-dom`, `@vue/compiler-ssr` |
| Compiler SFC | Single File Component (.vue) のコンパイル統合 | `@vue/compiler-sfc` |
| Server Rendering | サーバーサイドレンダリングのランタイム | `@vue/server-renderer` |
| Distribution | エンドユーザー向け統合パッケージ | `vue`, `@vue/compat` |

### レイヤー間の依存関係ルール

**許可される依存方向：**

- 上位レイヤーは下位レイヤーに依存できる（例：`runtime-core` → `reactivity` → `shared`）
- 同一レイヤー内のプラットフォーム実装はコアに依存する（例：`runtime-dom` → `runtime-core`）
- Distribution パッケージは全レイヤーに依存する

**禁止される依存方向：**

- 下位レイヤーから上位レイヤーへの依存（例：`shared` が `reactivity` に依存することは禁止）
- ランタイム層からコンパイラ層への直接依存（`vue` パッケージ内のブリッジを除く）
- `runtime-core` から DOM API への直接アクセス（`RendererOptions` インタフェースを通じた抽象化が必須）

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| リアクティビティ | 状態の変更検知と依存追跡による自動更新 | `@vue/reactivity` |
| コンポーネントモデル | コンポーネントのライフサイクル・Props・Emits・Slots管理 | `@vue/runtime-core` |
| 仮想DOM・レンダリング | VNode生成・差分検出・パッチ適用 | `@vue/runtime-core` (renderer, vnode) |
| DOMレンダリング | ブラウザDOM固有のノード操作・プロパティパッチ | `@vue/runtime-dom` |
| テンプレートコンパイル | テンプレート文字列 → レンダー関数のコード生成 | `@vue/compiler-core`, `@vue/compiler-dom` |
| SFCコンパイル | .vueファイルの解析と各ブロックのコンパイル統合 | `@vue/compiler-sfc` |
| SSRコンパイル | サーバーサイドレンダリング向けテンプレートコンパイル | `@vue/compiler-ssr` |
| SSRランタイム | サーバーサイドでのHTML文字列/ストリーム生成 | `@vue/server-renderer` |
| 共有ユーティリティ | 型チェック・DOM設定・パッチフラグ・文字列操作 | `@vue/shared` |
| Vue 2互換 | Vue 2 APIの互換レイヤー | `@vue/compat` |

### パッケージ構造

```
packages/
├── shared/                  # 共通ユーティリティ・定数
│   └── src/
│       ├── general.ts       # 汎用ユーティリティ (isArray, extend, hasOwn等)
│       ├── patchFlags.ts    # VNodeパッチ最適化フラグ
│       ├── shapeFlags.ts    # VNodeシェイプフラグ
│       └── ...              # (16ファイル)
├── reactivity/              # リアクティビティシステム
│   └── src/
│       ├── ref.ts           # ref/shallowRef実装
│       ├── reactive.ts      # reactive/readonly実装
│       ├── computed.ts      # 算出プロパティ
│       ├── effect.ts        # ReactiveEffect・依存追跡
│       ├── dep.ts           # 双方向リンクリストによる依存管理
│       ├── watch.ts         # watch/watchEffect
│       └── ...              # (13ファイル)
├── runtime-core/            # プラットフォーム非依存ランタイム
│   └── src/
│       ├── renderer.ts      # メインレンダラー
│       ├── vnode.ts         # VNode定義・生成
│       ├── component.ts     # コンポーネントインスタンス管理
│       ├── scheduler.ts     # ジョブスケジューラ・nextTick
│       ├── errorHandling.ts # エラーハンドリング
│       ├── apiCreateApp.ts  # createApp・プラグインシステム
│       ├── apiLifecycle.ts  # ライフサイクルフック
│       ├── components/      # 組み込みコンポーネント (KeepAlive, Teleport, Suspense等)
│       └── ...              # (50+ファイル)
├── runtime-dom/             # DOM固有ランタイム
│   └── src/
│       ├── nodeOps.ts       # DOM操作抽象化
│       ├── patchProp.ts     # DOMプロパティパッチ
│       ├── modules/         # 属性・クラス・スタイル・イベント処理
│       ├── directives/      # v-show, v-on, v-model
│       ├── components/      # Transition, TransitionGroup
│       └── ...              # (17ファイル)
├── compiler-core/           # プラットフォーム非依存コンパイラ
│   └── src/
│       ├── compile.ts       # メインコンパイルパイプライン
│       ├── parser.ts        # テンプレートパーサー
│       ├── tokenizer.ts     # 字句解析
│       ├── ast.ts           # AST型定義
│       ├── transform.ts     # AST変換フレームワーク
│       ├── codegen.ts       # コード生成
│       ├── transforms/      # ディレクティブ変換プラグイン (vIf, vFor, vOn等)
│       └── ...              # (30+ファイル)
├── compiler-dom/            # DOM固有コンパイラ拡張
│   └── src/
│       ├── parserOptions.ts # HTML固有パーサーオプション
│       ├── transforms/      # DOM固有変換 (vShow, vModel, stringifyStatic等)
│       └── ...              # (16ファイル)
├── compiler-sfc/            # SFCコンパイラ
│   └── src/
│       ├── parse.ts         # .vueファイルパーサー
│       ├── compileScript.ts # <script setup>コンパイル
│       ├── compileTemplate.ts # <template>コンパイル
│       ├── compileStyle.ts  # <style>コンパイル
│       ├── script/          # マクロ処理 (defineProps, defineEmits等)
│       ├── style/           # スコープCSS・CSS変数
│       └── ...              # (30ファイル)
├── compiler-ssr/            # SSRコンパイラ
│   └── src/
│       ├── ssrCodegenTransform.ts # SSR向けコード生成
│       ├── transforms/      # SSR固有変換
│       └── ...              # (17ファイル)
├── server-renderer/         # サーバーレンダラー
│   └── src/
│       ├── renderToString.ts # HTML文字列レンダリング
│       ├── renderToStream.ts # ストリームレンダリング
│       ├── helpers/         # SSRヘルパー関数
│       └── ...              # (15ファイル)
├── vue/                     # メイン配布パッケージ
│   └── src/
│       ├── index.ts         # フルビルドエントリ (ランタイム+コンパイラ)
│       ├── runtime.ts       # ランタイムのみエントリ
│       └── dev.ts           # 開発モード初期化
├── vue-compat/              # Vue 2互換ビルド
│   └── src/                 # (6ファイル)
├── runtime-test/            # テスト用仮想ランタイム
│   └── src/                 # (5ファイル)
└── global.d.ts              # グローバル型定義
```

### コンポーネント依存関係

パッケージ間の依存関係は厳格な一方向性を維持している。

```
@vue/shared (依存なし)
    ↑
@vue/reactivity → @vue/shared
    ↑
@vue/runtime-core → @vue/reactivity, @vue/shared
    ↑
@vue/runtime-dom → @vue/runtime-core, @vue/reactivity, @vue/shared
@vue/runtime-test → @vue/runtime-core, @vue/shared

@vue/compiler-core → @vue/shared, @babel/parser, entities, estree-walker, source-map-js
    ↑
@vue/compiler-dom → @vue/compiler-core, @vue/shared
    ↑
@vue/compiler-ssr → @vue/compiler-dom, @vue/shared
@vue/compiler-sfc → @vue/compiler-core, @vue/compiler-dom, @vue/compiler-ssr, @vue/shared,
                     @babel/parser, estree-walker, magic-string, postcss, source-map-js

@vue/server-renderer → @vue/compiler-ssr, @vue/shared (peer: vue)

vue → @vue/runtime-dom, @vue/compiler-dom, @vue/compiler-sfc, @vue/server-renderer, @vue/shared
@vue/compat → @babel/parser, estree-walker, source-map-js (peer: vue)
```

## ミドルウェア構成

### データベース

本プロジェクトはフロントエンドフレームワークであり、データベースミドルウェアは使用しない。

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| LRU Cache (インメモリ) | - | SFC パース結果のキャッシュ (`compiler-sfc/src/cache.ts`) | アプリケーションライフタイム |
| WeakMap (言語組み込み) | - | Proxy → リアクティブオブジェクトのマッピング (`reactivity/src/reactive.ts`) | GCに依存 |

### メッセージキュー

本プロジェクトでは外部メッセージキューは使用しない。ただし、内部的にジョブキュー（`runtime-core/src/scheduler.ts`）を実装し、コンポーネント更新のバッチ処理を行っている。

### 検索エンジン

該当なし。

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Rollup | ^4.57.0 | パッケージバンドル（ESM/CJS/IIFE形式） |
| esbuild | ^0.27.2 | TypeScript トランスパイル・開発ビルド |
| SWC | ^1.15.11 | プロダクションビルドのミニファイ |
| Vitest | ^3.2.4 | ユニットテスト・E2Eテスト |
| PostCSS | ^8.5.6 | SFCスタイルブロックのCSS変換 |

## データフロー

### リクエスト処理の流れ（テンプレートレンダリング）

1. ユーザーがテンプレート文字列またはレンダー関数を含むコンポーネントを定義する
2. `createApp()` でアプリケーションインスタンスを生成し、`app.mount()` でDOMに接続する
3. テンプレートが存在し、レンダー関数がない場合、`@vue/compiler-dom` がテンプレートをレンダー関数にコンパイルする（フルビルド時のみ。バンドラー利用時はビルド時にコンパイル済み）
4. `@vue/reactivity` のリアクティブエフェクトとしてレンダー関数が実行され、VNode ツリーが生成される
5. レンダラー（`@vue/runtime-core`）がVNodeツリーを差分比較（diff）し、パッチを生成する
6. `@vue/runtime-dom` の `nodeOps` がDOMに対してパッチを適用する

### 非同期処理の流れ（リアクティブ更新）

1. リアクティブデータが変更されると、`@vue/reactivity` の `trigger()` が依存するエフェクトに通知する
2. コンポーネント更新ジョブが `scheduler` の更新キューに登録される
3. スケジューラは `queueFlush()` でマイクロタスクとしてフラッシュをスケジュールする
4. フラッシュ時に3フェーズで処理される：
   - **Pre-flush**: ウォッチャーコールバック（`queueJob` with `PRE` flag）
   - **Main flush**: コンポーネント再レンダリング（`queueJob`）
   - **Post-flush**: DOM更新後のコールバック（`queuePostFlushCb`）
5. 再帰更新を検知するため、`RECURSION_LIMIT`（100回）が設定されている

### データ永続化の流れ

本プロジェクトはフロントエンドフレームワークであり、データ永続化機構は含まない。リアクティブ状態はすべてインメモリで管理される。

## 横断的関心事

### 認証・認可

本プロジェクトはUIフレームワークであり、認証・認可機構は含まない。

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| 開発警告 | `warn()` 関数 (`runtime-core/src/warning.ts`) でコンポーネントツリーのトレース付き警告を出力。`__DEV__` フラグにより本番ビルドで除去 | ブラウザコンソール |
| コンパイラエラー | `ErrorCodes` 列挙型によるエラー分類 (`compiler-core/src/errors.ts`) | コンパイル時例外 |
| DevTools連携 | `devtools.ts` (`runtime-core/src/devtools.ts`) によるコンポーネントインスペクション | Vue DevTools ブラウザ拡張 |
| パフォーマンスプロファイリング | `profiling.ts` (`runtime-core/src/profiling.ts`) による `performance.mark/measure` | ブラウザ Performance API |

### エラーハンドリング

Vue.js 3 は階層的なエラーハンドリング機構を持つ。

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| 同期エラー（セットアップ・レンダー関数等） | `callWithErrorHandling()` で try-catch ラップ | `errorCaptured` フック → 親コンポーネントへ伝播 → `app.config.errorHandler` |
| 非同期エラー（ライフサイクルフック等） | `callWithAsyncErrorHandling()` で Promise チェーンラップ | 同上 |
| コンパイルエラー | `createCompilerError()` / `createDOMCompilerError()` でエラーコードと位置情報を生成 | コンパイル時例外（ソースコードフレーム付き） |
| ハイドレーション不一致 | `__DEV__` モードで詳細な不一致情報を出力 | 開発時警告 + クライアント側再レンダリング |

エラーコードは `ErrorCodes` 列挙型で一元管理され、以下の実行コンテキストごとに分類される：
- `SETUP_FUNCTION`, `RENDER_FUNCTION`, `NATIVE_EVENT_HANDLER`, `COMPONENT_EVENT_HANDLER`, `VNODE_HOOK`, `DIRECTIVE_HOOK`, `WATCH_GETTER`, `WATCH_CALLBACK`, `WATCH_CLEANUP` 等

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| リアクティブ更新バッチ | スケジューラのジョブキューにより、同一マイクロタスク内の複数更新を1回のフラッシュにバッチ化 | ジョブID（コンポーネントUID）による重複排除 |
| エフェクトバッチ | `ReactiveEffect` の `batch()` メソッドにより、エフェクト実行を一括で遅延処理 | エフェクトスコープ（`EffectScope`）による分離 |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 関心の分離 (Separation of Concerns) | パッケージ分割全体 | ランタイム/コンパイラの明確な分離、プラットフォーム非依存コアとプラットフォーム固有実装の分離 |
| プラットフォーム抽象化 | `runtime-core` のレンダラー | `RendererOptions` インタフェースにより DOM 操作を抽象化。`runtime-dom` が DOM 実装、`runtime-test` がテスト実装を提供 |
| プラグインアーキテクチャ | コンパイラの変換パイプライン | `NodeTransform` と `DirectiveTransform` インタフェースにより、コンパイラ変換をプラグインとして追加可能 |
| Proxy パターン | リアクティビティシステム | `Proxy` API によるオブジェクトの読み書き操作のインターセプト。`baseHandlers.ts` と `collectionHandlers.ts` で trap を実装 |
| サブスクライバーパターン | 依存追跡 | `ReactiveEffect` と `Dep` の双方向リンクリストによる依存関係管理 |
| ビルダーパターン | `createApp()` API | `app.use()`, `app.component()`, `app.directive()` のチェーン呼び出しによるアプリケーション構築 |
| Tree-shaking 最適化 | ビルド全体 | フィーチャーフラグ（`__FEATURE_OPTIONS_API__`, `__FEATURE_SUSPENSE__` 等）による未使用コードの除去。`PatchFlags` による VNode パッチの最適化 |
| 遅延評価 | 算出プロパティ | `ComputedRefImpl` によるダーティチェックと遅延再計算 |

### コーディング規約

- **ターゲット**: ES2016（`async/await`、オプショナルチェーニング、オブジェクトスプレッドは使用禁止。ESLint で `no-restricted-syntax` にて強制）
- **TypeScript**: strict モード。`consistent-type-imports` によるインポート型の明示化。`isolatedDeclarations` の有効化
- **列挙型**: `const enum` は禁止。ビルド時にインライン化される通常の `enum` を使用（`scripts/inline-enums.js`）
- **オブジェクトスプレッド**: esbuild のトランスパイル結果が冗長になるため、`@vue/shared` の `extend` ヘルパーを使用
- **環境分離**: `eslint.config.js` にてパッケージごとにグローバル変数アクセスを制限（DOM系パッケージで Node グローバル禁止、Node系パッケージで DOM グローバル禁止）
- **フォーマット**: Prettier（TypeScript パーサー使用）、lint-staged による pre-commit 自動フォーマット
- **コミット規約**: conventional-changelog に準拠。`scripts/verify-commit.js` による検証
- **Git Hooks**: `simple-git-hooks` による pre-commit（lint + type check）と commit-msg（メッセージ検証）

## 備考

### ビルド形式

各パッケージは用途に応じて複数のビルド形式を出力する：

| ビルド形式 | フォーマット | 用途 |
| --- | --- | --- |
| `esm-bundler` | ES Modules | Webpack/Vite等のバンドラー向け（tree-shaking対応） |
| `esm-browser` | ES Modules | ブラウザ直接読み込み向け |
| `cjs` | CommonJS | Node.js 環境向け |
| `global` | IIFE | `<script>` タグ直接読み込み向け |
| `esm-bundler-runtime` | ES Modules | ランタイムのみビルド（コンパイラ除外） |
| `esm-browser-runtime` | ES Modules | ランタイムのみブラウザビルド |
| `global-runtime` | IIFE | ランタイムのみグローバルビルド |

### Vue 2 互換性

`@vue/compat` パッケージにより、Vue 2 API の互換レイヤーを提供する。Vue 3 内部を使用しつつ Vue 2 スタイルの API サーフェスを公開し、段階的な移行を支援する。`compiler-core` 内にも `compat/` ディレクトリがあり、Vue 2 のフィルター構文等の互換変換を提供する。

### テスト戦略

- **テストフレームワーク**: Vitest（3プロジェクト構成）
  - `unit`: DOM非依存のユニットテスト
  - `unit-jsdom`: jsdom環境のユニットテスト（`vue`, `vue-compat`, `runtime-dom`）
  - `e2e`: Puppeteer によるE2Eテスト
- **テスト用ランタイム**: `@vue/runtime-test` が仮想DOMランタイムを提供し、DOM無しでレンダリングロジックをテスト可能
