# 帳票設計書 6-SFCスクリプトコンパイル結果

## 概要

本ドキュメントは、Vue.jsのcompiler-sfcパッケージにおける`compileScript`関数が出力する`SFCScriptBlock`の設計仕様を記述する。SFCの`<script>`/`<script setup>`部をコンパイルし、defineProps、defineEmits、defineExpose等のマクロを処理してバインディングメタデータ付きのスクリプトコードを生成する。

### 本帳票の処理概要

compiler-sfcの`compileScript`関数は、SFCDescriptor全体とオプションを入力として受け取り、`<script>`と`<script setup>`の両方を統合処理する。defineProps/defineEmits/defineExpose/defineOptions/defineSlots/defineModelの各マクロを処理し、setup()関数内のコードをエクスポート可能な形式に変換し、バインディングメタデータ（テンプレートコンパイル最適化用）付きの`SFCScriptBlock`を出力する。

**業務上の目的・背景**：Vue 3の`<script setup>`構文は、Composition APIの冗長なボイラープレートを削減するSFC専用の構文糖である。compileScriptは`<script setup>`内のマクロ呼び出しを処理し、通常の`<script>`との統合、リアクティブな分割代入の変換（propsDestructure）、未使用インポートの除去（TypeScript用）等の高度な変換を行う。

**帳票の利用シーン**：SFCファイルのビルド時にscript部がコンパイルされる全ての場面。`<script setup>`を使用するコンポーネントでは必須の処理。

**主要な出力内容**：
1. `type` - 'script'（固定）
2. `content` - 変換後のスクリプトコード
3. `setup` - setup属性の値
4. `bindings` - バインディングメタデータ（BindingMetadata型）
5. `imports` - インポート情報
6. `scriptAst` - 通常`<script>`のAST
7. `scriptSetupAst` - `<script setup>`のAST
8. `warnings` - 警告配列
9. `deps` - 型解決で使用された依存ファイルパス
10. `lang` - スクリプト言語（ts/js等）
11. `map` - ソースマップ
12. `loc` - ソース位置情報
13. `attrs` - 属性情報

**帳票の出力タイミング**：SFCファイルのビルド時にscript部がコンパイルされる際に実行される。

**帳票の利用者**：@vitejs/plugin-vue、vue-loader、その他のSFCビルドプラグイン。

## 帳票種別

スクリプトコンパイル結果（データ構造出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | SFCビルドプロセス | - | SFCのscript部コンパイル時に自動実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JavaScript/TypeScript オブジェクト（インメモリ） |
| 用紙サイズ | 該当なし |
| 向き | 該当なし |
| ファイル名 | インメモリデータ |
| 出力方法 | 関数戻り値として返却（SFCScriptBlock型） |
| 文字コード | UTF-8 |

### PDF固有設定

該当なし

### Excel固有設定

該当なし

## 帳票レイアウト

### レイアウト概要

SFCScriptBlockはSFCBlockを拡張した構造で、script/script setup固有の情報を含む。

```
┌─────────────────────────────────────┐
│    SFCScriptBlock (extends SFCBlock)│
├─────────────────────────────────────┤
│  type: 'script'                     │
│  content: string                    │
│  （変換後スクリプトコード）            │
│  loc: SourceLocation                │
│  attrs: Record<string, string|true> │
│  lang?: string                      │
│  map?: RawSourceMap                 │
├─────────────────────────────────────┤
│  setup?: string | boolean           │
│  bindings?: BindingMetadata         │
│  （テンプレート最適化用メタデータ）    │
│  imports?: Record<string, ImportBinding> │
│  scriptAst?: Statement[]            │
│  scriptSetupAst?: Statement[]       │
│  warnings?: string[]                │
│  deps?: string[]                    │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | content | 変換後のスクリプトコード（defineProps等のマクロ処理済み） | compileScript変換結果 | string |
| 2 | bindings | テンプレート最適化用バインディングメタデータ | ScriptCompileContext | BindingMetadata |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | setup | setup属性の有無・値 | SFCDescriptor.scriptSetup | string / boolean / undefined | - |
| 2 | imports | インポートバインディング情報 | ScriptCompileContext | Record<string, ImportBinding> | - |
| 3 | scriptAst | 通常scriptのBabel AST | @babel/parser | Statement[] / undefined | - |
| 4 | scriptSetupAst | script setupのBabel AST | @babel/parser | Statement[] / undefined | - |
| 5 | warnings | 警告メッセージ | ScriptCompileContext | string[] / undefined | - |
| 6 | deps | 型解決で使用された依存ファイルパス | ScriptCompileContext | string[] / undefined | - |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | map | ソースマップ | SourceMapGenerator | RawSourceMap / undefined |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| sfc | SFCDescriptor（parse関数の出力） | Yes |
| options.id | スコープID | Yes |
| options.isProd | 本番モードフラグ | No |
| options.sourceMap | ソースマップ生成フラグ | No（デフォルト: true） |
| options.inlineTemplate | テンプレートインライン化フラグ | No |
| options.hoistStatic | 静的定数ホイスティングフラグ | No（デフォルト: true） |
| options.propsDestructure | props分割代入フラグ | No（デフォルト: true） |

### ソート順

該当なし

### 改ページ条件

該当なし

## データベース参照仕様

該当なし（インメモリ処理）

### 参照テーブル一覧

該当なし

### テーブル別参照項目詳細

該当なし

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| scopeId | options.id.replace(/^data-v-/, '') | - | CSS変数生成用 |
| hoistStatic | options.hoistStatic !== false && !script | - | 通常scriptがない場合のみ有効 |
| isJSOrTS | isJS(scriptLang, scriptSetupLang) \|\| isTS(scriptLang, scriptSetupLang) | - | 言語判定 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[compileScript呼び出し] --> B{scriptSetup存在?}
    B -->|なし| C[processNormalScript]
    C --> D[SFCScriptBlock返却]
    B -->|あり| E[ScriptCompileContext生成]
    E --> F[script/scriptSetupのAST解析]
    F --> G[マクロ処理]
    G --> H[defineProps処理]
    H --> I[defineEmits処理]
    I --> J[defineExpose処理]
    J --> K[defineOptions処理]
    K --> L[defineSlots処理]
    L --> M[defineModel処理]
    M --> N[propsDestructure処理]
    N --> O[未使用インポート除去]
    O --> P[最終コード生成]
    P --> Q[SFCScriptBlock構築・返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 言語不一致 | scriptとscriptSetupのlangが異なる | script and script setup must have the same language type | langを統一する |
| scriptなし | scriptもscriptSetupも存在しない | SFC contains no script tags | script/script setupを追加 |
| src属性不正 | script setupにsrc属性を指定 | script setup cannot use the "src" attribute | src属性を除去 |
| script src不正 | script setupと共存するscriptにsrc属性 | script cannot use the "src" attribute when script setup is also present | src属性を除去 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1 SFCにつき1回 |
| 目標出力時間 | ミリ秒オーダー |
| 同時出力数上限 | 制限なし（同期処理） |

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

compileScriptはマクロ処理を通じてコード変換を行うが、ユーザーが記述したコードの意味を変更しないことが保証される。TypeScript型情報はコンパイル時にのみ使用され、実行時には除去される。

## 備考

- `<script setup>`がない場合は`processNormalScript`が使用され、通常のスクリプトブロックの解析のみが行われる。
- マクロ（DEFINE_PROPS, DEFINE_EMITS, DEFINE_EXPOSE, DEFINE_OPTIONS, DEFINE_SLOTS, DEFINE_MODEL, WITH_DEFAULTS）はコンパイル時に処理され、実行時のランタイムには残らない。
- `inlineTemplate`オプションが有効な場合、テンプレートのrender関数がsetup()関数の戻り値として直接インライン化される。
- `hoistStatic`はscript setupのみで有効（通常scriptがない場合）で、静的な定数をmodule levelにホイスティングする。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parse.ts | `packages/compiler-sfc/src/parse.ts` | SFCScriptBlock型（50-64行目）- SFCBlockを拡張したscript固有の型 |
| 1-2 | compileScript.ts | `packages/compiler-sfc/src/compileScript.ts` | SFCScriptCompileOptions型（73-142行目）とImportBinding型（144-151行目） |

**読解のコツ**: SFCScriptBlockはSFCBlockの拡張であり、setup、bindings、imports等のscript setup固有フィールドが追加されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compileScript.ts | `packages/compiler-sfc/src/compileScript.ts` | compileScript関数（168行目〜）がエントリーポイント |

**主要処理フロー**:
1. **172-178行目**: options.idの検証とwarnOnce
2. **180行目**: SFCDescriptorからscript、scriptSetup、source、filenameを取得
3. **181行目**: hoistStaticフラグの計算
4. **188-193行目**: scriptとscriptSetupの言語不一致チェック
5. **195-200行目**: scriptSetupが存在しない場合はprocessNormalScriptへ委譲

#### 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 | context.ts | `packages/compiler-sfc/src/script/context.ts` | ScriptCompileContextクラス |
| 4-2 | normalScript.ts | `packages/compiler-sfc/src/script/normalScript.ts` | processNormalScript関数 |
| 4-3 | definePropsDestructure.ts | `packages/compiler-sfc/src/script/definePropsDestructure.ts` | props分割代入の変換 |
| 4-4 | importUsageCheck.ts | `packages/compiler-sfc/src/script/importUsageCheck.ts` | 未使用インポートの検出 |
| 4-5 | analyzeScriptBindings.ts | `packages/compiler-sfc/src/script/analyzeScriptBindings.ts` | バインディング解析 |

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

```
compileScript (compileScript.ts:168)
    |
    +-- [scriptSetupなし] processNormalScript (normalScript.ts)
    |       +-- analyzeScriptBindings
    |       +-- SFCScriptBlock を返却
    |
    +-- [scriptSetupあり] ScriptCompileContext生成 (context.ts)
            |
            +-- processDefineProps (defineProps.ts)
            +-- processDefineEmits (defineEmits.ts)
            +-- processDefineExpose (defineExpose.ts)
            +-- processDefineOptions (defineOptions.ts)
            +-- processDefineSlots (defineSlots.ts)
            +-- processDefineModel (defineModel.ts)
            |
            +-- transformDestructuredProps (definePropsDestructure.ts)
            +-- isImportUsed (importUsageCheck.ts)
            +-- processAwait (topLevelAwait.ts)
            |
            +-- [inlineTemplate] compileTemplate (compileTemplate.ts)
            |
            +-- genRuntimeProps (defineProps.ts)
            +-- genRuntimeEmits (defineEmits.ts)
            +-- genCssVarsCode (cssVars.ts)
            |
            +-- SFCScriptBlock を返却
```

### データフロー図

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

SFCDescriptor
  script             ──▶  Babel AST解析            ──▶  scriptAst
  scriptSetup        ──▶  Babel AST解析            ──▶  scriptSetupAst
  source                         |
  filename                 マクロ処理
                           (defineProps/Emits/Expose等)
SFCScriptCompileOptions          |
  id                       コード変換
  isProd             ──▶  (インポート整理、setup関数生成) ──▶  SFCScriptBlock
  inlineTemplate                                            { content, bindings,
  hoistStatic                                                imports, scriptAst,
                                                              scriptSetupAst, ... }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compileScript.ts | `packages/compiler-sfc/src/compileScript.ts` | ソース | compileScript関数、SFCScriptCompileOptions型 |
| parse.ts | `packages/compiler-sfc/src/parse.ts` | ソース | SFCScriptBlock型定義 |
| context.ts | `packages/compiler-sfc/src/script/context.ts` | ソース | ScriptCompileContextクラス |
| normalScript.ts | `packages/compiler-sfc/src/script/normalScript.ts` | ソース | processNormalScript関数 |
| 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マクロ処理 |
| definePropsDestructure.ts | `packages/compiler-sfc/src/script/definePropsDestructure.ts` | ソース | props分割代入変換 |
| importUsageCheck.ts | `packages/compiler-sfc/src/script/importUsageCheck.ts` | ソース | 未使用インポート検出 |
| analyzeScriptBindings.ts | `packages/compiler-sfc/src/script/analyzeScriptBindings.ts` | ソース | バインディング解析 |
| topLevelAwait.ts | `packages/compiler-sfc/src/script/topLevelAwait.ts` | ソース | トップレベルawait処理 |
| utils.ts | `packages/compiler-sfc/src/script/utils.ts` | ソース | ユーティリティ関数 |
