# 機能設計書 42-useCssModule()

## 概要

本ドキュメントは、Vue 3のSFC（Single File Component）において `<style module>` で定義されたCSSモジュールのクラス名マッピングにアクセスするためのComposition APIフック `useCssModule()` の機能設計を記述する。

### 本機能の処理概要

`useCssModule()` は、SFCの `<style module>` ブロックで定義されたCSSモジュールのクラス名マッピングをオブジェクトとして取得するフックである。CSS Modulesの仕組みにより、ローカルスコープ化されたクラス名をJavaScript内で動的に参照できる。

**業務上の目的・背景**：CSS Modulesは、クラス名の衝突を防止し、コンポーネント単位でCSSをカプセル化する手法である。テンプレート内では `$style` で直接参照できるが、Composition APIのsetup()関数内やレンダリング関数内でCSSモジュールのクラス名を参照する必要がある場面で、このフックが活用される。

**機能の利用シーン**：Composition APIのsetup()関数内で動的にクラス名を切り替える場合、レンダリング関数（h()やJSX）内でCSSモジュールのクラス名を参照する場合、カスタムロジックに基づいてクラスを条件付きで適用する場合に使用される。

**主要な処理内容**：
1. 現在のコンポーネントインスタンスを`getCurrentInstance()`で取得
2. インスタンスの型定義から`__cssModules`プロパティを参照
3. 指定されたモジュール名（デフォルト: `$style`）に対応するCSSクラスマッピングを返す

**関連システム・外部連携**：@vue/compiler-sfcによるSFCコンパイル時のCSSモジュール注入、@vue/runtime-coreのgetCurrentInstance()

**権限による制御**：権限制御は存在しない。グローバルビルドでは使用できない（__GLOBAL__フラグで制御）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに該当なし |

## 機能種別

参照取得（CSSモジュールアクセス）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | No | CSSモジュール名（デフォルト: `$style`） | なし |

### 入力データソース

- @vue/runtime-coreの`getCurrentInstance()`から取得されるコンポーネントインスタンス
- インスタンスのコンポーネント型定義に注入された`__cssModules`プロパティ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | Record<string, string> | CSSクラス名のマッピングオブジェクト（元のクラス名 -> スコープ化されたクラス名） |

### 出力先

呼び出し元のsetup()関数またはレンダリング関数内で利用される戻り値として出力。

## 処理フロー

### 処理シーケンス

```
1. グローバルビルド判定
   └─ __GLOBAL__ が true の場合: DEVモードで警告出力 → EMPTY_OBJ を返す
2. getCurrentInstance() でコンポーネントインスタンスを取得
   └─ インスタンスが存在しない場合: DEVモードで警告出力 → EMPTY_OBJ を返す
3. instance.type.__cssModules を取得
   └─ __cssModules が存在しない場合: DEVモードで警告出力 → EMPTY_OBJ を返す
4. modules[name] でモジュール名に対応するマッピングを取得
   └─ 指定名のモジュールが存在しない場合: DEVモードで警告出力 → EMPTY_OBJ を返す
5. CSSモジュールマッピングを返す
```

### フローチャート

```mermaid
flowchart TD
    A[useCssModule呼び出し] --> B{__GLOBAL__?}
    B -->|Yes| C[DEV警告: グローバルビルドでは未サポート]
    C --> D[EMPTY_OBJ を返す]
    B -->|No| E[getCurrentInstance]
    E --> F{instance が存在?}
    F -->|No| G[DEV警告: setup内で呼び出す必要あり]
    G --> D
    F -->|Yes| H{__cssModules が存在?}
    H -->|No| I[DEV警告: CSSモジュールが注入されていない]
    I --> D
    H -->|Yes| J{modules[name] が存在?}
    J -->|No| K[DEV警告: 指定名のCSSモジュールがない]
    K --> D
    J -->|Yes| L[CSSモジュールマッピングを返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | デフォルトモジュール名 | nameパラメータのデフォルト値は`$style` | name未指定時 |
| BR-42-02 | グローバルビルド制限 | グローバルビルド（CDN経由）ではuseCssModule()は使用不可 | __GLOBAL__がtrueの場合 |
| BR-42-03 | setup内呼び出し | setup()関数内でのみ呼び出し可能 | 常時 |
| BR-42-04 | フォールバック | エラー時はEMPTY_OBJ（空のフリーズオブジェクト）を返す | エラー発生時 |

### 計算ロジック

特別な計算ロジックは存在しない。

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

データベース操作は存在しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告（DEVのみ） | グローバルビルドで呼び出した場合 | バンドラー経由のビルドを使用すること |
| - | 警告（DEVのみ） | setup()外で呼び出した場合 | setup()内で呼び出すこと |
| - | 警告（DEVのみ） | CSSモジュールが注入されていない場合 | `<style module>`を使用すること |
| - | 警告（DEVのみ） | 指定名のモジュールが存在しない場合 | モジュール名を確認すること |

### リトライ仕様

リトライ仕様は存在しない。

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

トランザクション処理は存在しない。

## パフォーマンス要件

軽量なプロパティアクセス処理であり、特別なパフォーマンス要件はない。

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

- CSSモジュールのクラス名はビルド時にハッシュ化されるため、CSSインジェクション攻撃のリスクは低い
- 返却されるオブジェクトは読み取り専用として扱うべき

## 備考

- `<style module="custom">` と定義した場合、`useCssModule('custom')` で取得可能
- `__cssModules` プロパティはSFCコンパイラ（@vue/compiler-sfc）がコンパイル時に注入する
- EMPTY_OBJは@vue/sharedパッケージで定義されている空のフリーズオブジェクト

---

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

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

### 推奨読解順序

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

CSSモジュールの注入構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | useCssModule.ts | `packages/runtime-dom/src/helpers/useCssModule.ts` | 全体の実装（わずか31行）を把握する。instance.type.__cssModulesがCSSモジュール格納先 |

**読解のコツ**: `__cssModules` はコンポーネントの型定義（instance.type）に注入されるプロパティで、SFCコンパイラが生成するコードによって設定される。キーがモジュール名（`$style`等）、値がクラス名のマッピングオブジェクトとなる。

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

useCssModule()関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | useCssModule.ts | `packages/runtime-dom/src/helpers/useCssModule.ts` | useCssModule関数定義（4行目）: デフォルトパラメータname = '$style' |

**主要処理フロー**:
1. **5行目**: `__GLOBAL__`フラグでグローバルビルドかどうかを判定
2. **6行目**: `getCurrentInstance()` でコンポーネントインスタンスを取得
3. **7-9行目**: インスタンス存在チェック。なければ警告 + EMPTY_OBJ返却
4. **11行目**: `instance.type.__cssModules` でCSSモジュールマッピングを取得
5. **12-15行目**: モジュールが存在しなければ警告 + EMPTY_OBJ返却
6. **16-19行目**: 指定名のモジュールが存在しなければ警告 + EMPTY_OBJ返却
7. **22行目**: モジュールのクラスマッピングを `Record<string, string>` として返す

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

```
useCssModule(name = '$style')
    │
    ├─ getCurrentInstance()  [@vue/runtime-core]
    │
    ├─ instance.type.__cssModules  (SFCコンパイラが注入)
    │
    └─ modules[name]  → Record<string, string>
```

### データフロー図

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

<style module>        ──▶ SFCコンパイラが__cssModulesに注入
(SFCコンパイル時)

useCssModule(name)    ──▶ getCurrentInstance()          ──▶ Record<string, string>
                          │                                  (クラス名マッピング)
                          ├─ instance.type.__cssModules
                          │
                          └─ modules[name] 取得
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| useCssModule.ts | `packages/runtime-dom/src/helpers/useCssModule.ts` | ソース | useCssModule()の実装（全31行） |
| index.ts | `packages/runtime-dom/src/index.ts` | ソース | useCssModuleのエクスポート |
