# 機能設計書 34-HTMLバンドル

## 概要

本ドキュメントは、BunバンドラーにおけるHTMLバンドル機能の設計仕様を記載する。HTMLバンドルは、HTMLファイルをエントリーポイントとして処理し、HTMLからインポートされるJavaScript、CSS、画像などのアセットを自動的にバンドルする機能である。

### 本機能の処理概要

HTMLバンドルは、HTMLファイル内の`<script>`タグ、`<link>`タグ、画像参照などを解析し、関連するアセットを自動的にバンドルして、最適化されたHTMLとアセット群を出力する機能である。

**業務上の目的・背景**：従来のバンドラーでは、JavaScriptファイルをエントリーポイントとして指定する必要があった。しかし、多くのWebアプリケーションではHTMLファイルが実際のエントリーポイントであり、HTMLから参照されるアセットを自動的に処理できることで、開発ワークフローがより直感的になる。HTMLをインポートした際に、関連ファイルのメタデータ（パス、ハッシュ、MIME タイプなど）を取得できるため、サーバーサイドでの動的配信にも対応できる。

**機能の利用シーン**：静的サイトジェネレーション、SPAのビルド、マルチページアプリケーション、サーバーサイドレンダリングとの統合時に利用される。JavaScriptからHTMLをインポートすると、そのHTMLに関連するすべてのファイルのマニフェストが取得できる。

**主要な処理内容**：
1. HTMLファイルのパースとアセット参照の検出
2. `<script>` タグのJavaScriptバンドル
3. `<link rel="stylesheet">` タグのCSSバンドル
4. 画像やその他アセットの処理
5. HTMLImportManifest（インポートマニフェスト）の生成
6. 参照パスの更新と最終HTML出力

**関連システム・外部連携**：JavaScriptバンドラー、CSSバンドラーと連携して動作する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | build | 主画面 | バンドル処理実行時のHTMLバンドル適用 |

## 機能種別

バンドル処理 / アセット処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| entry_points | []string | Yes | HTMLファイルを含むエントリーポイント | .htmlファイルを含む |
| public_path | string | No | 公開パスのプレフィックス | デフォルト: "" |
| asset_naming | string | No | アセットファイルの命名パターン | デフォルト: "[name]-[hash].[ext]" |

### 入力データソース

- HTMLファイル
- HTMLから参照されるJavaScript/CSS/画像ファイル
- CLI/APIオプション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| HTMLファイル | ファイル | アセット参照が更新された最終HTML |
| JSバンドル | ファイル | HTMLから参照されるJavaScriptのバンドル |
| CSSバンドル | ファイル | HTMLから参照されるCSSのバンドル |
| アセットファイル | ファイル | 画像やその他のアセット |
| HTMLImportManifest | JSON | インポート時に取得できるマニフェスト |

### 出力先

ファイルシステム（指定された出力ディレクトリ）

## 処理フロー

### 処理シーケンス

```
1. HTMLファイルパース
   └─ HTMLを解析してアセット参照を検出
2. アセット収集
   └─ script、link、img等からアセットパスを抽出
3. 依存アセットのバンドル
   └─ JSはJSバンドラー、CSSはCSSバンドラーで処理
4. アセットファイルの処理
   └─ 画像等のファイルをコピー（必要に応じてハッシュ付き）
5. HTMLImportManifest生成
   └─ 全アセットのメタデータをJSON形式で生成
6. HTML更新
   └─ アセット参照を最終パスに更新
7. 出力
   └─ HTML、アセット、マニフェストを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: HTMLファイル入力] --> B[HTMLパース]
    B --> C[アセット参照検出]
    C --> D{アセットタイプ判定}
    D -->|JavaScript| E[JSバンドラーで処理]
    D -->|CSS| F[CSSバンドラーで処理]
    D -->|画像等| G[ファイルコピー+ハッシュ]
    E --> H[パス更新]
    F --> H
    G --> H
    H --> I[HTMLImportManifest生成]
    I --> J[HTML出力]
    J --> K[終了: バンドル完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-001 | アセット検出 | script[src]、link[href]、img[src]等からアセットを自動検出 | HTML処理時 |
| BR-34-002 | ハッシュ命名 | アセットファイルにはコンテンツハッシュを付与 | デフォルト設定時 |
| BR-34-003 | マニフェスト生成 | HTMLインポート時はマニフェストJSONを返す | JSからHTMLインポート時 |
| BR-34-004 | ETag生成 | 各ファイルにETagヘッダー情報を含む | マニフェスト生成時 |

### 計算ロジック

**HTMLImportManifest構造**:
- `index`: オリジナルHTMLファイルパス
- `files`: 生成されたファイルの配列
  - `input`: 元ファイルパス
  - `path`: 出力ファイルパス（ハッシュ付き）
  - `loader`: ファイルタイプ（js, css, html, file等）
  - `isEntry`: エントリーポイントかどうか
  - `headers`: ETag、Content-Type等のヘッダー情報

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | 参照アセット未検出 | ファイルパスを確認 |
| - | エラー | HTMLパースエラー | HTML構文を確認 |
| - | エラー | --no-bundleでHTMLインポート | bundlingを有効にする |

### リトライ仕様

リトライは行わない。

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

該当なし（ファイル処理のみ）

## パフォーマンス要件

- HTMLパースとアセット処理は並列実行可能
- 大量のアセットを含むHTMLでも効率的に処理

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

- 外部URLへの参照は処理対象外
- ETagにはコンテンツハッシュを使用し、キャッシュ制御に活用可能

## 備考

- `--compile`オプションと組み合わせることで、単一実行ファイルにHTMLを埋め込み可能
- サーバーサイドでHTMLをインポートすると、クライアント向けファイルのマニフェストが取得可能

---

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

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

### 推奨読解順序

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

まず、HTMLバンドルで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HTMLImportManifest.zig | `src/bundler/HTMLImportManifest.zig` | HTMLインポートマニフェストの構造と生成ロジック |
| 1-2 | Chunk.zig | `src/bundler/Chunk.zig` | HTMLチャンク（content = .html）の定義 |

**読解のコツ**: HTMLImportManifest.zigのドキュメントコメント（1-34行目）がマニフェストの構造と目的を詳しく説明している。

#### Step 2: HTMLチャンク処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | computeChunks.zig | `src/bundler/linker_context/computeChunks.zig` | HTMLチャンクの作成（64-79行目） |
| 2-2 | generateCompileResultForHtmlChunk.zig | `src/bundler/linker_context/generateCompileResultForHtmlChunk.zig` | HTMLチャンクのコード生成 |

**主要処理フロー**:
- **64-79行目**: has_html_chunkフラグでHTMLチャンクを判定
- **64-79行目**: html_chunksマップにHTMLチャンクを登録

#### Step 3: マニフェスト生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HTMLImportManifest.zig | `src/bundler/HTMLImportManifest.zig` | write()関数でマニフェストJSON生成 |

**主要処理フロー**:
- **52-95行目**: writeEntryItem()で各ファイルエントリを生成
- **120-200行目**: write()でマニフェスト全体を構築
- **77-94行目**: ETag、Content-Typeヘッダーの生成

#### Step 4: HTMLポスト処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | postProcessHTMLChunk.zig | `src/bundler/linker_context/postProcessHTMLChunk.zig` | HTMLチャンクの後処理、パス更新 |

**主要処理フロー**:
- アセット参照の最終パスへの更新
- スクリプト、スタイルシートのインライン化（オプション）

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

```
BundleV2.bundle()
    │
    ├─ ParseTask (HTML)
    │      └─ HTMLファイルのパース
    │
    └─ LinkerContext
           ├─ computeChunks()
           │      ├─ JSチャンク作成
           │      ├─ CSSチャンク作成
           │      └─ HTMLチャンク作成
           │
           ├─ generateCompileResultForHtmlChunk()
           │      └─ HTMLコード生成
           │
           ├─ postProcessHTMLChunk()
           │      └─ パス更新、最終HTML生成
           │
           └─ HTMLImportManifest.write()
                  └─ マニフェストJSON生成
```

### データフロー図

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

HTMLファイル ─────▶ HTMLパース ───▶ アセット参照リスト
       │
       ▼
アセット参照 ─────▶ 各バンドラー処理 ───▶ バンドルファイル
       │                                    │
       ▼                                    ▼
バンドルファイル ──▶ パス更新 ───▶ 最終HTML
       │
       ▼
全ファイル情報 ───▶ HTMLImportManifest.write() ───▶ マニフェストJSON
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HTMLImportManifest.zig | `src/bundler/HTMLImportManifest.zig` | ソース | マニフェスト生成 |
| computeChunks.zig | `src/bundler/linker_context/computeChunks.zig` | ソース | HTMLチャンク計算 |
| generateCompileResultForHtmlChunk.zig | `src/bundler/linker_context/generateCompileResultForHtmlChunk.zig` | ソース | HTMLコード生成 |
| postProcessHTMLChunk.zig | `src/bundler/linker_context/postProcessHTMLChunk.zig` | ソース | HTML後処理 |
| Chunk.zig | `src/bundler/Chunk.zig` | ソース | チャンク構造定義 |
| build_command.zig | `src/cli/build_command.zig` | ソース | CLIオプション処理 |
