# 機能設計書 55-compileScript()

## 概要

本ドキュメントは、@vue/compiler-sfcパッケージにおけるcompileScript()関数の処理について記述する。SFCの`<script>`および`<script setup>`ブロックをコンパイルし、Props/Emitsの自動抽出、型定義解析、バインディングメタデータの生成を行う。

### 本機能の処理概要

compileScript()は、SFCDescriptorから取得したスクリプトブロックを処理し、Composition APIのマクロ（defineProps、defineEmits、defineExpose等）の変換、型情報の抽出、バインディングメタデータの生成を行う。`<script setup>`と通常の`<script>`の両方に対応し、それらが併存する場合のマージ処理も担う。

**業務上の目的・背景**：`<script setup>`構文はVue 3.2で導入されたSFCの簡潔なスクリプト記法であり、コンパイル時にボイラープレートコードを自動生成する。compileScript()はこの構文を標準的なJavaScriptに変換し、型安全性を維持しながらランタイムで実行可能なコードを出力する。

**機能の利用シーン**：SFCのビルド時にparse()の後に呼び出される。Viteプラグイン（@vitejs/plugin-vue）やvue-loaderから使用される。テンプレートのインラインコンパイルにも対応する。

**主要な処理内容**：
1. `<script setup>`内のコンパイラマクロ（defineProps/defineEmits/defineExpose/defineOptions/defineSlots/defineModel）の処理
2. withDefaults()によるPropsデフォルト値の処理
3. バインディングメタデータの生成（Props/Setup/Data/Options各バインディングの分類）
4. import文の使用状況チェックとツリーシェイキング
5. 通常`<script>`との統合（スクリプトコンテキストの共有）
6. top-level awaitのサポート
7. CSS変数ヘルパーコードの生成
8. テンプレートのインラインコンパイル
9. ソースマップの生成

**関連システム・外部連携**：@babel/parserによるスクリプト解析。compileTemplate()によるインラインテンプレートコンパイル。TypeScript型推論システムとの連携。

**権限による制御**：該当なし（コンパイル時処理）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | App（メイン画面） | API連携 | @vue/replコンポーネントを介した`<script setup>`ブロックのコンパイル |

## 機能種別

スクリプトコンパイル処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sfc | SFCDescriptor | Yes | parse()の結果であるSFC記述子 | script/scriptSetupの少なくとも一方が存在 |
| options.id | string | Yes | スコープID（CSS変数プレフィックス用） | - |
| options.isProd | boolean | No | プロダクションモード | デフォルト: false |
| options.sourceMap | boolean | No | ソースマップ生成有無 | デフォルト: true |
| options.babelParserPlugins | ParserPlugin[] | No | Babelパーサープラグイン | - |
| options.inlineTemplate | boolean | No | テンプレートのインラインコンパイル | デフォルト: false |
| options.genDefaultAs | string | No | デフォルトエクスポートの変数名 | - |
| options.templateOptions | Partial<SFCTemplateCompileOptions> | No | テンプレートコンパイルオプション | - |
| options.hoistStatic | boolean | No | 静的定数のホイスティング | デフォルト: true |
| options.propsDestructure | boolean \| 'error' | No | PropsのReactive Destructure | デフォルト: true |
| options.fs | FileSystemAccess | No | 型解決用のファイルシステムアクセス | - |
| options.customElement | boolean \| Function | No | カスタム要素モード | - |

### 入力データソース

parse()により生成されたSFCDescriptorのscript/scriptSetupブロック。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | SFCScriptBlock | コンパイル済みスクリプトブロック（content, bindings, imports, deps等） |

### 出力先

SFCScriptBlockとして返却される。ビルドツールがモジュールコードとして出力する。

## 処理フロー

### 処理シーケンス

```
1. 事前チェック
   └─ scriptSetupが無い場合: processNormalScriptで通常スクリプトのみ処理
   └─ 非JS/TS言語の場合: そのまま返却

2. ScriptCompileContextの生成
   └─ Babel ASTの構築（script/scriptSetup両方）
   └─ MagicStringによるコード変換準備

3. 通常`<script>`の解析
   └─ default exportの検出
   └─ import文のメタデータ収集
   └─ バインディング種別の分析

4. `<script setup>`の解析
   └─ import文の処理（テンプレート使用状況チェック付き）
   └─ コンパイラマクロの検出と処理:
      - defineProps() → propsの型/値抽出
      - defineEmits() → emitsの型/値抽出
      - defineExpose() → 公開インターフェース定義
      - defineOptions() → コンポーネントオプション定義
      - defineSlots() → スロット型定義
      - defineModel() → v-modelバインディング定義
      - withDefaults() → Propsデフォルト値設定
   └─ top-level awaitの検出と変換
   └─ 変数宣言のバインディング種別分析

5. テンプレートのインラインコンパイル（オプション）
   └─ compileTemplate()を呼び出し
   └─ レンダリング関数をsetup()内に埋め込み

6. 静的定数のホイスティング

7. 最終コードの組み立て
   └─ ランタイムPropsの生成
   └─ ランタイムEmitsの生成
   └─ CSS変数ヘルパーの生成
   └─ setup()関数のラッピング
   └─ コンポーネントオブジェクトの生成

8. ソースマップの生成と返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: compileScript] --> B{scriptSetupあり?}
    B -->|No| C[processNormalScript]
    B -->|Yes| D[ScriptCompileContext生成]
    D --> E[通常script解析]
    E --> F[script setup解析]
    F --> G[マクロ検出・処理]
    G --> H{インラインテンプレート?}
    H -->|Yes| I[compileTemplate呼び出し]
    H -->|No| J[バインディングメタデータ生成]
    I --> J
    J --> K[最終コード組み立て]
    K --> L[ソースマップ生成]
    L --> M[SFCScriptBlock返却]
    C --> N[終了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-55-01 | 言語一致 | `<script>`と`<script setup>`は同じ言語でなければならない | 両方存在する場合 |
| BR-55-02 | マクロスコープ制限 | defineProps等のマクロはsetup()のトップレベルでのみ使用可能 | ネストされたスコープ内での使用はエラー |
| BR-55-03 | ローカル変数参照禁止 | defineOptions()等ではローカル変数を参照不可（ホイストされるため） | setupBindingsに登録済みの変数を参照した場合 |
| BR-55-04 | 型エクスポート除去 | TypeScript型のみのimportはランタイムコードから除去 | isType=trueのimport |
| BR-55-05 | テンプレート使用チェック | TypeScript環境ではテンプレートで未使用のimportを除去 | isTS && template存在 && src/langなし |

### 計算ロジック

バインディング種別の分類:
- `const x = ref()`: SETUP_REF
- `const x = reactive()`: SETUP_REACTIVE_CONST
- `const x = computed()`: SETUP_REF
- `let x = ...`: SETUP_LET
- `const x = 'literal'`: LITERAL_CONST
- `const x = ...`: SETUP_CONST（上記以外）
- Props: PROPS
- Data: DATA
- Options API: OPTIONS

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

該当なし（コンパイル時処理のため、データベース操作は発生しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | `<script>`と`<script setup>`の言語が不一致 | 同じ言語に統一する |
| - | Error | SFCに`<script>`タグが存在しない | `<script>`を追加する |
| - | Error | マクロのローカル変数参照 | 通常の`<script>`でオプションを定義する |

### リトライ仕様

該当なし

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

該当なし（コンパイル時処理）

## パフォーマンス要件

- テンプレート使用チェックにより、不要なimportを除去してバンドルサイズを削減
- hoistStaticにより、静的定数をsetup()外にホイストして初期化コストを削減
- インラインテンプレートにより、別ファイルのレンダリング関数呼び出しのオーバーヘッドを削減

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

該当なし（コンパイル時処理）

## 備考

- MACROSリスト: DEFINE_PROPS, DEFINE_EMITS, DEFINE_EXPOSE, DEFINE_OPTIONS, DEFINE_SLOTS, DEFINE_MODEL, WITH_DEFAULTS
- Reactive Destructure（propsDestructure）はVue 3.5で安定化された機能
- genDefaultAsオプションは@vitejs/plugin-vueでメインモジュール内にスクリプトを配置するために使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parse.ts | `packages/compiler-sfc/src/parse.ts` | SFCScriptBlock型（bindings, imports, scriptAst, scriptSetupAst） |
| 1-2 | compileScript.ts | `packages/compiler-sfc/src/compileScript.ts` | SFCScriptCompileOptions、ImportBinding型定義 |
| 1-3 | context.ts | `packages/compiler-sfc/src/script/context.ts` | ScriptCompileContext型（内部状態管理） |

**読解のコツ**: ScriptCompileContextは内部状態をカプセル化し、各マクロ処理関数がこのコンテキストを共有する。MagicString（ctx.s）によるコード変換が中心的な手法である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compileScript.ts | `packages/compiler-sfc/src/compileScript.ts` | compileScript()関数 |

**主要処理フロー**:
1. **168-178行目**: 事前チェック（id, scriptSetup存在確認）
2. **180-207行目**: 言語チェック、scriptSetup無しの場合のprocessNormalScript
3. **215行目**: ScriptCompileContext生成
4. **299行目**: scriptAstの取得と通常スクリプト解析開始

#### Step 3: マクロ処理の詳細

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | defineProps.ts | `packages/compiler-sfc/src/script/defineProps.ts` | defineProps()マクロの処理 |
| 3-2 | defineEmits.ts | `packages/compiler-sfc/src/script/defineEmits.ts` | defineEmits()マクロの処理 |
| 3-3 | defineExpose.ts | `packages/compiler-sfc/src/script/defineExpose.ts` | defineExpose()マクロの処理 |
| 3-4 | defineOptions.ts | `packages/compiler-sfc/src/script/defineOptions.ts` | defineOptions()マクロの処理 |
| 3-5 | defineSlots.ts | `packages/compiler-sfc/src/script/defineSlots.ts` | defineSlots()マクロの処理 |
| 3-6 | defineModel.ts | `packages/compiler-sfc/src/script/defineModel.ts` | defineModel()マクロの処理 |

#### Step 4: バインディング解析

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | analyzeScriptBindings.ts | `packages/compiler-sfc/src/script/analyzeScriptBindings.ts` | 通常スクリプトのバインディング分析 |
| 4-2 | importUsageCheck.ts | `packages/compiler-sfc/src/script/importUsageCheck.ts` | テンプレート内のimport使用状況チェック |

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

```
compileScript (エントリーポイント)
    │
    ├─ processNormalScript (scriptSetup無し時)
    │
    ├─ ScriptCompileContext (コンテキスト生成)
    │
    ├─ processDefineProps
    │      └─ genRuntimeProps
    ├─ processDefineEmits
    │      └─ genRuntimeEmits
    ├─ processDefineExpose
    ├─ processDefineOptions
    ├─ processDefineSlots
    ├─ processDefineModel
    │
    ├─ transformDestructuredProps (Reactive Destructure)
    │
    ├─ processAwait (top-level await)
    │
    ├─ compileTemplate (インラインモード)
    │
    ├─ analyzeScriptBindings
    │
    ├─ isImportUsed (テンプレート使用チェック)
    │
    └─ genCssVarsCode (CSS変数ヘルパー)
```

### データフロー図

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

SFCDescriptor      ───▶ compileScript            ───▶ SFCScriptBlock
├─ script                │                            ├─ content (コード)
├─ scriptSetup           ├─ マクロ処理                ├─ bindings
└─ template              │   defineProps → Props型      │   (メタデータ)
                         │   defineEmits → Emits型      ├─ imports
                         │                            ├─ scriptAst
                         ├─ バインディング解析          ├─ scriptSetupAst
                         │   → SETUP_REF等             └─ deps
                         │
                         └─ コード生成
                             → setup()関数ラッピング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compileScript.ts | `packages/compiler-sfc/src/compileScript.ts` | ソース | スクリプトコンパイラのメイン実装 |
| context.ts | `packages/compiler-sfc/src/script/context.ts` | ソース | ScriptCompileContext（内部状態管理） |
| defineProps.ts | `packages/compiler-sfc/src/script/defineProps.ts` | ソース | defineProps()マクロ処理 |
| defineEmits.ts | `packages/compiler-sfc/src/script/defineEmits.ts` | ソース | defineEmits()マクロ処理 |
| defineExpose.ts | `packages/compiler-sfc/src/script/defineExpose.ts` | ソース | defineExpose()マクロ処理 |
| defineOptions.ts | `packages/compiler-sfc/src/script/defineOptions.ts` | ソース | defineOptions()マクロ処理 |
| defineSlots.ts | `packages/compiler-sfc/src/script/defineSlots.ts` | ソース | defineSlots()マクロ処理 |
| defineModel.ts | `packages/compiler-sfc/src/script/defineModel.ts` | ソース | defineModel()マクロ処理 |
| normalScript.ts | `packages/compiler-sfc/src/script/normalScript.ts` | ソース | 通常スクリプトの処理 |
| analyzeScriptBindings.ts | `packages/compiler-sfc/src/script/analyzeScriptBindings.ts` | ソース | バインディング分析 |
| importUsageCheck.ts | `packages/compiler-sfc/src/script/importUsageCheck.ts` | ソース | テンプレートimport使用チェック |
| definePropsDestructure.ts | `packages/compiler-sfc/src/script/definePropsDestructure.ts` | ソース | Reactive Destructure変換 |
| topLevelAwait.ts | `packages/compiler-sfc/src/script/topLevelAwait.ts` | ソース | top-level await処理 |
| cssVars.ts | `packages/compiler-sfc/src/style/cssVars.ts` | ソース | CSS変数ヘルパーコード生成 |
