# バッチ設計書 6-usage-size.js

## 概要

本ドキュメントは、Vue.jsプロジェクトのAPI使用パターン別バンドルサイズ計測スクリプト `scripts/usage-size.js` の設計仕様を定義するバッチ設計書である。

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

本バッチは、Vueの主要API使用パターン（createApp, createSSRApp, defineCustomElement等）ごとにRollupでバンドルを生成し、SWCによるminify後のサイズ（raw, gzip, brotli）を計測してJSON結果を出力するスクリプトである。

**業務上の目的・背景**：Vue.jsフレームワークのエンドユーザーは、使用するAPIによって異なるバンドルサイズの影響を受ける。例えばOptions APIを無効化した場合のcreateAppと、デフォルト設定のcreateAppではバンドルサイズが異なる。本バッチは、各API使用パターンにおける実効的なバンドルサイズを計測することで、tree-shakingの効果を定量化し、フレームワーク開発者がバンドルサイズの回帰を検知できるようにする。

**バッチの実行タイミング**：CI/CDパイプライン（`size-data.yml`ワークフロー）から `pnpm run size` コマンドの一部として呼び出される。開発者がローカルで手動実行することも可能。

**主要な処理内容**：
1. 定義済みプリセット（API使用パターン）ごとにRollupバンドルを生成
2. 仮想エントリポイントから対象APIのみをimportするバンドルを作成
3. SWC（`@swc/core`）によるminify処理
4. minify後のコードに対するgzip/brotli圧縮サイズの計測
5. 結果をコンソールに表示し、`temp/size/_usages.json` に保存

**前後の処理との関連**：本バッチの入力として `packages/vue/dist/vue.runtime.esm-bundler.js` が必要であり、事前に `build.js` によるビルドが完了している必要がある。出力された `_usages.json` は `scripts/size-report.js` によるサイズ比較レポートの入力データとなる。

**影響範囲**：`temp/size/_usages.json` にサイズ計測結果が出力される。`--write` オプション指定時は各プリセットのバンドル済みJavaScriptファイルも `temp/size/` に出力される。

## バッチ種別

サイズ計測

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルド後・CI/CDパイプライン内 |
| 実行時刻 | - |
| 実行曜日 | - |
| 実行日 | - |
| トリガー | pnpm run size コマンド / 手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.js実行環境 | Node.jsがインストールされていること |
| ビルド済み成果物 | `packages/vue/dist/vue.runtime.esm-bundler.js` が存在すること |
| 依存パッケージ | rollup, @rollup/plugin-node-resolve, @rollup/plugin-replace, @swc/core がインストール済み |

### 実行可否判定

エントリポイントファイル（`packages/vue/dist/vue.runtime.esm-bundler.js`）が存在すれば実行可能。存在しない場合はRollupバンドル時にエラーとなる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --write | boolean | No | false | 各プリセットのバンドル済みJSファイルをtemp/sizeに出力 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| packages/vue/dist/vue.runtime.esm-bundler.js | JavaScript | Vueのランタイムバンドル（ESM形式） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| temp/size/_usages.json | JSON | 全プリセットのサイズ計測結果 |
| temp/size/{preset.name}.js | JavaScript | --write指定時のバンドル済みファイル |
| 標準出力 | テキスト | 各プリセットのサイズ情報（min/gzip/brotli） |

### 出力ファイル仕様

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

## 処理フロー

### 処理シーケンス

```
1. プリセット定義の読み込み
   └─ 5つのプリセットを定義：
       - createApp (CAPI only): Options API無効化
       - createApp: デフォルト設定
       - createSSRApp: SSRアプリ
       - defineCustomElement: カスタム要素
       - overall: 複数API組み合わせ
2. 各プリセットのバンドル生成（並列実行）
   2.1 仮想エントリポイント作成
       └─ `export { imports } from 'vue.runtime.esm-bundler.js'` を動的生成
   2.2 Rollupバンドル
       └─ node-resolveプラグイン、replaceプラグインを適用
       └─ process.env.NODE_ENV → "production" に置換
       └─ __VUE_PROD_DEVTOOLS__ → "false" に置換
       └─ __VUE_OPTIONS_API__ → プリセット設定に基づく値
   2.3 SWCによるminify
       └─ module: true, toplevel: true オプション
   2.4 gzip/brotli圧縮サイズの計測
3. 結果の表示と保存
   └─ コンソールにサイズ情報を出力（prettyBytes使用、小数点3桁）
   └─ temp/size/_usages.jsonに全結果をJSON保存
   └─ --write指定時はバンドル済みJSファイルも保存
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[プリセット定義読み込み]
    B --> C[プリセットごとの並列バンドル生成]
    C --> D[仮想エントリポイント作成]
    D --> E[Rollupバンドル実行]
    E --> F[SWCによるminify]
    F --> G[gzip/brotliサイズ計測]
    G --> H[Promise.allで全結果を集約]
    H --> I[コンソールにサイズ表示]
    I --> J[_usages.jsonに保存]
    J --> K{--write指定?}
    K -->|Yes| L[バンドルJSファイル保存]
    K -->|No| M[バッチ終了]
    L --> M
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Rollupバンドルエラー | エントリポイントファイルが存在しない | build.jsを事前に実行してビルド成果物を生成 |
| - | SWC minifyエラー | バンドルコードの構文エラー | ビルド成果物を再生成 |

### リトライ仕様

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

### 障害時対応

バンドル生成に失敗した場合はPromise.allによりエラーが伝搬する。build.jsを再実行してビルド成果物を再生成後に再実行する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 各プリセットのバンドル生成が独立 |
| コミットタイミング | _usages.json書き込み時 |
| ロールバック条件 | 部分的な結果の書き込みは行われない（Promise.allで全結果集約後に書き込み） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 5プリセット |
| 目標処理時間 | Rollupバンドル+SWC minifyのため数秒〜十数秒 |
| メモリ使用量上限 | 明示的な制限なし |

## 排他制御

temp/size/ディレクトリへの書き込みがあるため、同時実行は想定されていない。build.jsの--sizeオプションとの同時実行時にファイル競合の可能性がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| サイズ情報 | 全プリセット処理完了後 | プリセット名、minサイズ、gzipサイズ、brotliサイズ（小数点3桁） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| - | - | CI/CDワークフロー内で処理されるため個別の監視は不要 |

## 備考

- 仮想エントリポイント（`virtual:entry`）を使用してRollupプラグインで動的にコードを生成する設計
- `@rollup/plugin-replace` により `process.env.NODE_ENV` を `"production"` に固定
- `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__` は `"false"` に設定
- SWCのminifyオプションとして `module: true`, `toplevel: true` を使用し、最大限のminificationを実行
- `prettyBytes` のオプションで `minimumFractionDigits: 3` を指定して小数点以下3桁まで表示
- プリセット「createApp (CAPI only)」では `__VUE_OPTIONS_API__` を `"false"` に設定し、Options APIを除外したサイズを計測
