# バッチ設計書 4-inline-enums.js

## 概要

本ドキュメントは、Vue.jsプロジェクトのTypeScript enumインライン変換スクリプト `scripts/inline-enums.js` の設計仕様を定義するバッチ設計書である。

### 本バッチの処理概要

本バッチは、プロジェクト内のTypeScript enumをスキャンし、ビルド時にオブジェクトリテラルへのインライン変換を行うためのキャッシュデータを生成するスクリプトである。Rollupプラグインとしても機能し、ビルドプロセス中にenum宣言をオブジェクトリテラルに書き換える。

**業務上の目的・背景**：Vue.jsプロジェクトではconst enumの使用に関する問題（#1228）が発生したため、通常のenumに切り替えた。しかし、const enumのゼロコスト（バンドルサイズに影響しない）という利点は維持したい。本バッチは通常のenum宣言を前処理してオブジェクトリテラルに変換することで、const enumと同等のバンドルサイズ最適化を実現する。ビルド時にenum値がリテラルに置換されるため、tree-shakingも効果的に機能する。

**バッチの実行タイミング**：`scripts/build.js` のビルドプロセス開始時に `scanEnums()` として自動的に呼び出される。Rollupプラグインとしては各ファイルのトランスフォーム時に実行される。

**主要な処理内容**：
1. `git grep` コマンドで `export enum` を含むファイルを検索
2. 検出されたファイルを `@babel/parser` でASTに解析
3. enum宣言のメンバー情報（名前、値）を収集
4. 値の解決（リテラル値、バイナリ式、単項式、自動インクリメント）
5. enum変換データをJSONキャッシュファイル（`temp/enum.json`）に保存
6. Rollupプラグインによるビルド時のenum宣言書き換え（オブジェクトリテラルへの変換）

**前後の処理との関連**：本バッチの `scanEnums()` 関数は `scripts/build.js` から直接呼び出される。生成されたキャッシュデータは `rollup.config.js` 内で `inlineEnums()` 関数を通じてRollupプラグインとして使用される。ビルド完了後、キャッシュファイルは `build.js` のfinallyブロックで削除される。

**影響範囲**：`temp/enum.json` にキャッシュデータが一時的に生成される。Rollupビルド中にenum宣言を含むファイルのソースコードが変換される（ファイル自体は変更されない）。ビルド成果物においてenum値がインライン化される。

## バッチ種別

解析処理（コード変換前処理）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルド時（build.jsから呼び出し） |
| 実行時刻 | - |
| 実行曜日 | - |
| 実行日 | - |
| トリガー | build.jsからの関数呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Gitリポジトリ | `git grep` コマンドが実行可能であること |
| Node.js実行環境 | Node.jsがインストールされていること |
| @babel/parser | 依存パッケージがインストール済みであること |
| magic-string | 依存パッケージがインストール済みであること |
| プロジェクトルート | プロジェクトルートディレクトリをcwdとして実行すること |

### 実行可否判定

特別な実行可否判定はない。`git grep` でenum宣言が見つからない場合は空のキャッシュデータが生成される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| - | - | - | - | コマンドライン引数なし（関数として呼び出される） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| プロジェクト内TypeScriptファイル | TypeScript | `export enum` を含む全ファイル（git grepで検索） |
| temp/enum.json | JSON | inlineEnums()関数使用時のキャッシュデータ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| temp/enum.json | JSON | enum変換データキャッシュ（declarations, defines） |
| Rollupトランスフォーム出力 | JavaScript | enum宣言がオブジェクトリテラルに変換されたコード |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | `enum.json` |
| 出力先 | `temp/` |
| 文字コード | UTF-8 |
| 区切り文字 | - |

## 処理フロー

### 処理シーケンス

```
1. scanEnums()の実行
   1.1 git grepで "export enum" を含むファイルを検索
       └─ 出力からファイルパスを抽出し、重複を除去
   1.2 各ファイルを@babel/parserでAST解析
       └─ TypeScriptプラグインを有効化
   1.3 ExportNamedDeclaration > TSEnumDeclarationノードを抽出
       └─ 同一ファイル内の宣言マージは禁止（エラーをスロー）
   1.4 各enumメンバーの値を解決
       └─ StringLiteral / NumericLiteral: そのまま使用
       └─ BinaryExpression: 左辺・右辺を再帰的に解決して評価
       └─ UnaryExpression: 引数を解決して評価
       └─ 初期化子なし: 前値からの自動インクリメント（数値のみ）
   1.5 defines辞書に `{enumId}.{memberName}` → JSON文字列値 を登録
       └─ 名前衝突がある場合はエラーをスロー
   1.6 temp/ディレクトリ作成（存在しない場合）
   1.7 temp/enum.jsonにキャッシュデータを書き込み
   1.8 クリーンアップ関数を返却（temp/enum.jsonを削除する関数）
2. inlineEnums()の実行（Rollupプラグインとして）
   2.1 temp/enum.jsonからキャッシュデータを読み込み
   2.2 transformフック内でenum宣言をオブジェクトリテラルに書き換え
       └─ MagicStringを使用してソースコードを部分的に置換
       └─ 数値enumはリバースマッピングも生成
       └─ 文字列enumはフォワードマッピングのみ
   2.3 [plugin, defines]のタプルを返却
```

### フローチャート

```mermaid
flowchart TD
    A[scanEnums開始] --> B[git grep export enum実行]
    B --> C[対象ファイル一覧取得]
    C --> D[各ファイルをAST解析]
    D --> E[TSEnumDeclarationを抽出]
    E --> F{宣言マージ検出?}
    F -->|Yes| G[エラー終了]
    F -->|No| H[メンバー値を解決]
    H --> I{名前衝突?}
    I -->|Yes| G
    I -->|No| J[defines辞書に登録]
    J --> K[temp/enum.jsonに書き込み]
    K --> L[クリーンアップ関数を返却]
    L --> M[scanEnums完了]
```

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

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

本バッチはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 宣言マージエラー | 同一ファイル内に同名のenum宣言が複数存在 | enum名を変更するか、ファイルを分離 |
| - | 名前衝突エラー | 異なるファイルの同名enum内に同名のメンバーが存在 | メンバー名を変更（__EXTEND_POINT__等の特殊キーが対象） |
| - | 未対応初期化子エラー | サポートされていないenum初期化式の使用 | StringLiteral, NumericLiteral, BinaryExpression, UnaryExpressionのいずれかに変更 |
| - | キャッシュ未初期化エラー | inlineEnums()がscanEnums()の実行前に呼ばれた | build.jsを通じてscanEnums()を先に実行 |
| - | 自動インクリメント不正エラー | 文字列値の後に初期化子なしのメンバーが続く | 明示的な初期化子を追加 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | リトライ機構なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

### 障害時対応

enumスキャンの失敗はbuild.jsのtry-finallyブロックで捕捉される。失敗時もfinallyブロックでtemp/enum.jsonの削除が実行される。エラーメッセージにはファイルパスとenum名が含まれるため、問題箇所を特定しやすい。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 全enumのスキャンと一括書き込み |
| コミットタイミング | writeFileSync完了時 |
| ロールバック条件 | エラー発生時はキャッシュファイルが不完全なまま残る可能性があるが、finallyで削除される |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | プロジェクト内の全export enum宣言 |
| 目標処理時間 | git grepとAST解析のため秒単位 |
| メモリ使用量上限 | 明示的な制限なし |

## 排他制御

scanEnums()の実行後、inlineEnums()が呼ばれるまでキャッシュファイル（temp/enum.json）が共有リソースとなる。並列Rollupプロセス間でこのキャッシュファイルを読み取り専用で共有する設計となっている。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| - | - | 正常時のログ出力はなし。エラー時のみErrorがスローされる |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| - | - | build.jsのエラーハンドリングに委任 |

## 備考

- 本スクリプトは `scanEnums()` と `inlineEnums()` の2つの関数をエクスポートする
- `scanEnums()` はビルドスクリプトのエントリで1回呼ばれ、並列Rollupプロセス間でキャッシュを共有する
- TypeScriptのリバースマッピング仕様に準拠：数値enumは双方向マッピング、文字列enumはフォワードマッピングのみ
- `new Function()` によるenum値の動的評価を使用（BinaryExpression等の計算）
- const enumの代替としてバンドルサイズ最適化を実現する設計
- MagicStringライブラリによりソースマップ対応の部分的なコード置換を行う
