# 画面設計書 23-Route B

## 概要

本ドキュメントは、webpack virtual-modules サンプルにおけるルートB（Route B）の画面設計書である。Route B は、VirtualUrlPlugin により仮想的に生成されるルーティングシステムの一部として、動的 `import()` によって遅延読み込みされるルートモジュールである。

### 本画面の処理概要

Route B は、webpack の実験的機能である VirtualUrlPlugin を活用した仮想モジュールシステムのルーティングデモにおいて、動的にインポートされるルートの一つである。Route A と同じルーティングシステムに属し、同様のメカニズムで読み込まれる。

**業務上の目的・背景**：webpack 5 の VirtualUrlPlugin（実験的機能）を使用した仮想モジュール（Virtual Modules）の実証を行うサンプルの一部である。仮想モジュールシステムでは、プログラムによってモジュール内容を動的に生成できる。Route B は Route A と共にルーティングシステムの動的生成を実証するためのルートモジュールである。`virtual:routes` 仮想モジュールが `routesPath` ディレクトリをスキャンして検出されたファイルに対応する動的 `import()` を自動生成するため、ルートの追加・削除がファイルの追加・削除だけで完結する仕組みのデモンストレーションとなっている。

**画面へのアクセス方法**：example.js がエントリポイントとなり、`virtual:routes` 仮想モジュールから routes オブジェクトをインポートする。その後、`loadRoute("b")` を呼び出すことで Route B の内容が動的にインポートされる。

**主要な操作・処理内容**：
1. `virtual:routes` 仮想モジュールが `routes/` ディレクトリをスキャンし、各ファイルに対して `() => import('./routes/${key}')` の形式でルートマップを生成する
2. `loadRoute("b")` が呼び出されると、`routes["b"]()` が実行され、`import('./routes/b.js')` による動的インポートが発生する
3. `routes/b.js` の default export（文字列 `"b"`）が返される
4. 結果が `console.log` に出力される

**画面遷移**：本ルートは独立したルートモジュールであり、明示的な画面遷移は定義されていない。`loadRoute` 関数を通じて Route A と並列的にアクセス可能である。

**権限による表示制御**：権限による表示制御は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | 動的インポート | 主機能 | 動的import()によるルートの遅延読み込み |
| 3 | モジュール処理 | 補助機能 | 仮想モジュールシステムで生成されるルートモジュールの処理 |

## 画面種別

ルートモジュール（データ出力）

## URL/ルーティング

ルーティングは `virtual:routes` 仮想モジュールによって動的に管理される。ルートキーは `"b"` であり、`loadRoute("b")` によりアクセスされる。ターゲットが `node` 環境（`target: "node"`）であるため、ブラウザURLは存在しない。

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| route | 入力 | string | 必須 | ルートキー。Route B の場合は `"b"` |
| default export | 出力 | string | - | ルートモジュールの返却値。文字列 `"b"` |

## 表示項目

| 表示項目 | データソース | 表示形式 | 説明 |
|----------|-------------|----------|------|
| ルート値 | routes/b.js の default export | console.log出力 | 文字列 `"b"` がコンソールに出力される |

## イベント仕様

### 1-ルート読み込み

`loadRoute("b")` が呼び出された際の処理フロー。

1. `routes["b"]` 関数が呼び出される。この関数は `virtual:routes` 仮想モジュールにより `() => import('./routes/b.js')` として生成されている
2. webpack が動的 `import()` を処理し、`routes/b.js` のチャンクを非同期に読み込む
3. モジュールの default export（文字列 `"b"`）が Promise として返される
4. `await` により解決され、`.default` プロパティで値が取得される
5. `console.log` で結果が出力される

## データベース更新仕様

### 操作別データベース影響一覧

本画面にデータベース操作は存在しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| - | コンソール出力 | `"b"` | loadRoute("b") の実行時 |

## 例外処理

| 例外 | 発生条件 | 対応 |
|------|----------|------|
| モジュール解決エラー | routes/b.js ファイルが存在しない場合 | webpack ビルド時にモジュール解決エラーが発生する |
| チャンク読み込みエラー | 動的インポートのチャンク読み込みに失敗した場合 | Promise が reject され、呼び出し元で未処理の例外が発生する |

## 備考

- Route B は Route A と同一の仮想モジュールルーティングシステムに属しており、同じ `virtual:routes` 仮想モジュールから参照される
- `virtual:routes` の source 関数は `loaderContext.addContextDependency(routesPath)` を使用しており、routes ディレクトリへのファイル追加・削除を監視してモジュールの再ビルドをトリガーする
- ターゲットが `node` であるため、ブラウザ環境ではなく Node.js 環境で実行されることを前提としている
- Route B のモジュール内容は非常にシンプルで、`export default "b"` の1行のみである
- example.js では Route A の読み込み（21行目）の直後に Route B の読み込み（22行目）が逐次的に実行される

---

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

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

### 推奨読解順序

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

Route B が返すデータと、ルーティングシステムの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | b.js | `examples/virtual-modules/routes/b.js` | ルートモジュールの内容。`export default "b"` の1行のみ |

**読解のコツ**: ES Modules の default export パターン。モジュールの返却値は文字列 `"b"` のみ。Route A と対称的な構造である。

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

仮想モジュールを通じたルーティングの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | example.js | `examples/virtual-modules/example.js` | 15-22行目で `virtual:routes` からルートマップをインポートし、`loadRoute` 関数でルートを遅延読み込みする |

**主要処理フロー**:
1. **15行目**: `import { routes } from "virtual:routes"` で仮想モジュールからルートマップを取得
2. **17-19行目**: `async function loadRoute(route)` 関数定義。`routes[route]()` で動的インポートを実行し、`.default` で値を取得
3. **22行目**: `console.log(await loadRoute("b"))` で Route B を読み込み、結果を出力

#### Step 3: 仮想モジュールシステムを理解する

VirtualUrlPlugin の設定と、ルートマップの動的生成方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | webpack.config.js | `examples/virtual-modules/webpack.config.js` | 55-68行目の `routes` 仮想モジュール定義を確認。source関数がroutesディレクトリを走査し、動的import文を含むモジュールを生成する |

**主要処理フロー**:
- **7行目**: `const routesPath = path.join(__dirname, "./routes")` でルートディレクトリパスを設定
- **56行目**: `source(loaderContext)` 関数でモジュール内容を動的に生成
- **59行目**: `loaderContext.addContextDependency(routesPath)` でディレクトリの変更監視を設定
- **61行目**: `fs.readdirSync(routesPath)` でルートディレクトリのファイル一覧を取得
- **63-66行目**: 各ファイルに対して `${key.split(".")[0]}: () => import('./routes/${key}')` の形式でルートエントリを生成

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

```
example.js (エントリポイント)
    │
    ├─ import { routes } from "virtual:routes"
    │      └─ VirtualUrlPlugin (webpack.config.js)
    │             └─ source(loaderContext)
    │                    ├─ addContextDependency(routesPath)
    │                    ├─ fs.readdirSync(routesPath)
    │                    └─ 動的import文の生成
    │                           ├─ a: () => import('./routes/a.js')
    │                           └─ b: () => import('./routes/b.js')
    │
    └─ loadRoute("b")
           └─ routes["b"]()
                  └─ import('./routes/b.js')
                         └─ export default "b"
```

### データフロー図

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

routes/ディレクトリ
  │
  ├─ a.js                ───▶ VirtualUrlPlugin              ───▶ virtual:routes
  └─ b.js                     (ディレクトリスキャン)               (ルートマップ生成)
                                                                    │
loadRoute("b")           ───▶ routes["b"]()                 ───▶ import('./routes/b.js')
                               (動的import実行)                      │
                                                                    └─ "b" ───▶ console.log
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| b.js | `examples/virtual-modules/routes/b.js` | ソース | Route B のルートモジュール。default export で文字列 "b" を返す |
| example.js | `examples/virtual-modules/example.js` | ソース | エントリポイント。仮想モジュールの利用とルートの読み込み |
| webpack.config.js | `examples/virtual-modules/webpack.config.js` | 設定 | VirtualUrlPlugin設定。仮想モジュール定義とルートマップ生成 |
| a.js | `examples/virtual-modules/routes/a.js` | ソース | Route A のルートモジュール。Route B と同じルーティングシステム内 |
| code.js | `examples/virtual-modules/code.js` | ソース | 別の仮想モジュール（virtual:code-from-file）のソースファイル |
| typescript.ts | `examples/virtual-modules/typescript.ts` | ソース | TypeScriptローダーの設定用（ts-loader）|
| tsconfig.json | `examples/virtual-modules/tsconfig.json` | 設定 | TypeScript設定ファイル |
