# 帳票設計書 5-SFCスタイルコンパイル結果

## 概要

本ドキュメントは、Vue.jsのcompiler-sfcパッケージにおける`compileStyle`/`compileStyleAsync`関数が出力する`SFCStyleCompileResults`の設計仕様を記述する。SFCの`<style>`部をコンパイルし、PostCSSによる処理、scoped CSS、CSS Modules、CSS変数の解決を行う。

### 本帳票の処理概要

compiler-sfcの`compileStyle`（同期版）および`compileStyleAsync`（非同期版）関数は、SFCのstyle部のソースコードとオプションを入力として受け取り、PostCSSパイプラインを通じてCSS変数解決、トリム、スコープ付加、CSS Modules処理を行い、`SFCStyleCompileResults`を出力する。

**業務上の目的・背景**：Vue SFCの`<style>`ブロックは、scoped属性によるスコープ付きCSS、CSS Modules、CSS変数（v-bind()）、プリプロセッサ（SCSS/LESS/Stylus）等の独自機能をサポートする。compileStyleはこれらの機能をPostCSSプラグインチェーンで処理し、標準CSSに変換する。

**帳票の利用シーン**：SFCファイルのビルド時にstyle部が処理される全ての場面。CSS Modulesを使用する場合はcompileStyleAsync（非同期版）が必要。

**主要な出力内容**：
1. `code` - 処理済みCSSコード文字列
2. `map` - ソースマップ（オプション）
3. `rawResult` - PostCSSの生結果（Result / LazyResult）
4. `errors` - エラー配列
5. `modules` - CSS Modulesのマッピング（オプション）
6. `dependencies` - 依存ファイルパスのSet

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

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

## 帳票種別

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

## 利用画面

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

## 出力形式

### 基本仕様

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

### PDF固有設定

該当なし

### Excel固有設定

該当なし

## 帳票レイアウト

### レイアウト概要

SFCStyleCompileResultsは6つのフィールドで構成される。

```
┌─────────────────────────────────────┐
│    SFCStyleCompileResults           │
├─────────────────────────────────────┤
│  code: string                       │
│  （処理済みCSSコード）                │
├─────────────────────────────────────┤
│  map: RawSourceMap | undefined      │
├─────────────────────────────────────┤
│  rawResult: Result | LazyResult     │
│           | undefined               │
├─────────────────────────────────────┤
│  errors: Error[]                    │
├─────────────────────────────────────┤
│  modules?: Record<string, string>   │
│  （CSS Modulesマッピング）            │
├─────────────────────────────────────┤
│  dependencies: Set<string>          │
│  （依存ファイルパス）                 │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | code | 処理済みCSSコード（スコープID付与、CSS変数解決済み） | result.css | string |
| 2 | map | ソースマップ | result.map.toJSON() | RawSourceMap / undefined |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | rawResult | PostCSSの生結果オブジェクト | postcss().process() | Result / LazyResult / undefined | - |
| 2 | errors | プリプロセッサエラー + PostCSSエラー | preProcessedSource.errors + catch | Error[] | - |
| 3 | modules | CSS Modulesのクラス名マッピング（非同期版のみ） | postcss-modules getJSON | Record<string, string> / undefined | - |
| 4 | dependencies | 依存ファイルパスのセット（@import等で参照されるファイル） | preProcessedSource.dependencies + result.messages | Set<string> | - |

### フッター部

該当なし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| source | CSSソース文字列 | Yes |
| filename | SFCファイル名 | Yes |
| id | スコープID | Yes |
| scoped | スコープ付きCSS有効フラグ | No（デフォルト: false） |
| trim | トリム処理有効フラグ | No（デフォルト: true） |
| modules | CSS Modules有効フラグ（非同期版のみ） | No（デフォルト: false） |
| preprocessLang | プリプロセッサ言語（scss/less/stylus） | No |
| postcssPlugins | カスタムPostCSSプラグイン | No |

### ソート順

該当なし

### 改ページ条件

該当なし

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

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

### 参照テーブル一覧

該当なし

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

該当なし

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| shortId | id.replace(/^data-v-/, '') | - | CSS変数プラグイン用 |
| longId | `data-v-${shortId}` | - | scopedプラグイン用属性セレクター |
| PostCSSプラグインチェーン | [cssVarsPlugin, ...postcssPlugins, trimPlugin?, scopedPlugin?, postcssModules?] | - | 条件に応じてプラグインを追加 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[compileStyle/compileStyleAsync呼び出し] --> B[doCompileStyle]
    B --> C{preprocessLang?}
    C -->|あり| D[プリプロセッサ実行]
    C -->|なし| E[ソースをそのまま使用]
    D --> F[PostCSSプラグインチェーン構築]
    E --> F
    F --> G[cssVarsPlugin追加]
    G --> H{trim?}
    H -->|true| I[trimPlugin追加]
    H -->|false| J[スキップ]
    I --> K{scoped?}
    J --> K
    K -->|true| L[scopedPlugin追加]
    K -->|false| M[スキップ]
    L --> N{modules?}
    M --> N
    N -->|true| O[postcssModules追加]
    N -->|false| P[スキップ]
    O --> Q[postcss().process実行]
    P --> Q
    Q --> R{isAsync?}
    R -->|true| S[Promise返却]
    R -->|false| T[同期結果返却]
    S --> U[SFCStyleCompileResults]
    T --> U
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| プリプロセッサエラー | SCSS/LESS/Stylus等のコンパイルエラー | プリプロセッサ固有のメッセージ | ソースコードを修正 |
| PostCSS処理エラー | PostCSSプラグインのエラー | PostCSS固有のメッセージ | CSSを修正 |
| ブラウザビルドでmodules指定 | __GLOBAL__/__ESM_BROWSER__でmodules使用 | modules option is not supported in the browser build | 非ブラウザビルドで実行 |
| 同期版でmodules指定 | isAsync=falseでmodules使用 | modules option can only be used with compileStyleAsync() | compileStyleAsyncを使用 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1 SFCのstyleブロックにつき1回（複数styleブロック対応） |
| 目標出力時間 | ミリ秒〜秒オーダー（プリプロセッサ・PostCSSプラグインに依存） |
| 同時出力数上限 | 制限なし |

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

scoped CSSは属性セレクター（[data-v-xxxxxx]）によりスコープ化されるが、CSSの完全な分離を保証するものではない。CSS Modulesのクラス名はハッシュ化されるが、これはセキュリティではなく名前衝突回避のためである。

## 備考

- `compileStyle`は同期版で、CSS Modulesを使用しない場合に適している。CSS Modulesを使用する場合は`compileStyleAsync`を使用する必要がある。
- PostCSSプラグインの実行順序は重要：cssVarsPlugin -> [ユーザープラグイン] -> trimPlugin -> scopedPlugin -> postcssModules
- 依存ファイル（dependencies）はStylusのプリプロセッサとPostCSSのdependencyメッセージから収集される。ファイル名自身は依存関係から除外される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | compileStyle.ts | `packages/compiler-sfc/src/compileStyle.ts` | SFCStyleCompileResults型（62-69行目）を確認 |
| 1-2 | compileStyle.ts | `packages/compiler-sfc/src/compileStyle.ts` | SFCStyleCompileOptions型（20-37行目）とSFCAsyncStyleCompileOptions型（54-60行目）を確認 |
| 1-3 | compileStyle.ts | `packages/compiler-sfc/src/compileStyle.ts` | CSSModulesOptions型（43-52行目）を確認 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compileStyle.ts | `packages/compiler-sfc/src/compileStyle.ts` | compileStyle関数（71-78行目）とcompileStyleAsync関数（80-87行目）- 同期/非同期の薄いラッパー |

**主要処理フロー**:
1. **71-78行目**: compileStyleはdoCompileStyleをisAsync:falseで呼び出し
2. **80-87行目**: compileStyleAsyncはdoCompileStyleをisAsync:trueで呼び出し

#### Step 3: 内部処理（doCompileStyle）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | compileStyle.ts | `packages/compiler-sfc/src/compileStyle.ts` | doCompileStyle関数（89-220行目）が実際の処理 |

**主要処理フロー**:
- **104行目**: プリプロセッサの取得
- **105行目**: プリプロセッサによる前処理
- **114-121行目**: PostCSSプラグインチェーンの構築（cssVarsPlugin, trimPlugin, scopedPlugin）
- **122-142行目**: CSS Modules有効時のpostcssModulesプラグイン追加
- **144-155行目**: PostCSSオプション設定（ソースマップ含む）
- **182-203行目**: postcss().process()実行。非同期時はPromise、同期時は直接結果を返す

#### Step 4: PostCSSプラグインを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | pluginTrim.ts | `packages/compiler-sfc/src/style/pluginTrim.ts` | CSS先頭/末尾のトリム処理 |
| 4-2 | pluginScoped.ts | `packages/compiler-sfc/src/style/pluginScoped.ts` | scoped CSS（属性セレクター付加） |
| 4-3 | cssVars.ts | `packages/compiler-sfc/src/style/cssVars.ts` | v-bind() CSS変数の解決 |

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

```
compileStyle (compileStyle.ts:71) / compileStyleAsync (compileStyle.ts:80)
    |
    +-- doCompileStyle (compileStyle.ts:89)
            |
            +-- preprocess (compileStyle.ts:222) [preprocessLang指定時]
            |       +-- processors[preprocessLang]() (SCSS/LESS/Stylus)
            |
            +-- PostCSSプラグインチェーン構築
            |       +-- cssVarsPlugin (style/cssVars.ts)
            |       +-- trimPlugin (style/pluginTrim.ts) [trim=true]
            |       +-- scopedPlugin (style/pluginScoped.ts) [scoped=true]
            |       +-- postcssModules [modules=true, async only]
            |
            +-- postcss(plugins).process(source, postCSSOptions)
            |
            +-- SFCStyleCompileResults を返却
```

### データフロー図

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

SFCStyleCompileOptions
  source             ──▶  preprocess (SCSS等)     ──▶  前処理済みCSS
  filename                       |
  id                       PostCSSパイプライン
  scoped                   ┌──────────────────┐
  trim               ──▶  │ cssVarsPlugin      │ ──▶  CSS変数解決済み
  modules                  │ trimPlugin         │ ──▶  トリム済み
  preprocessLang           │ scopedPlugin       │ ──▶  スコープID付与済み
                           │ postcssModules     │ ──▶  CSS Modules解決
                           └──────────────────┘
                                 |
                           ────────────────────────▶  SFCStyleCompileResults
                                                        { code, map, rawResult,
                                                          errors, modules, dependencies }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compileStyle.ts | `packages/compiler-sfc/src/compileStyle.ts` | ソース | compileStyle/compileStyleAsync関数、doCompileStyle |
| pluginTrim.ts | `packages/compiler-sfc/src/style/pluginTrim.ts` | ソース | CSSトリムPostCSSプラグイン |
| pluginScoped.ts | `packages/compiler-sfc/src/style/pluginScoped.ts` | ソース | scoped CSS PostCSSプラグイン |
| cssVars.ts | `packages/compiler-sfc/src/style/cssVars.ts` | ソース | CSS変数（v-bind）PostCSSプラグイン |
| preprocessors.ts | `packages/compiler-sfc/src/style/preprocessors.ts` | ソース | SCSS/LESS/Stylusプリプロセッサ |
