# 機能設計書 36-ソースマップ

## 概要

本ドキュメントは、Bunバンドラーにおけるソースマップ（Source Map）機能の設計仕様を記載する。ソースマップは、バンドル・トランスパイル後のコードを元のソースコードにマッピングし、デバッグを容易にする機能である。

### 本機能の処理概要

ソースマップ機能は、JavaScript/TypeScriptのバンドル時に、生成されたコードと元のソースコードの対応関係を記録したマッピングファイルを生成する。これにより、ブラウザの開発者ツールやNode.jsのデバッガーで、バンドル後のコードをデバッグする際に元のソースコードを参照できる。

**業務上の目的・背景**：モダンなJavaScript開発では、TypeScript、JSX、最新のECMAScript構文など、ブラウザで直接実行できないコードを使用することが一般的である。これらのコードはトランスパイルやバンドルによって変換されるが、本番環境でのエラー調査やデバッグ時には元のソースコードを参照できることが重要である。ソースマップにより、変換後のコードから元のソースコードの行番号・列番号を特定でき、効率的なデバッグが可能となる。

**機能の利用シーン**：開発時のデバッグ、本番環境でのエラートラッキング、スタックトレースの可読性向上時に利用される。`--sourcemap`オプションで有効化する。

**主要な処理内容**：
1. 各ソースファイルの行オフセットテーブル計算
2. コード生成時のマッピング情報収集
3. VLQ（Variable Length Quantity）エンコーディング
4. ソースマップJSONまたはインラインData URL生成
5. 元ソースコードの引用（sourcesContent）

**関連システム・外部連携**：ブラウザ開発者ツール、Node.jsデバッガー、エラートラッキングサービス（Sentry等）と連携。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | build | 主画面 | --sourcemapオプションによるソースマップ生成 |

## 機能種別

デバッグ支援 / メタデータ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source_maps | SourceMapOption | No | ソースマップの生成モード | none, linked, inline, external |
| sourcemap | string | No | CLIオプション形式 | none, linked, inline, external |

### 入力データソース

- JavaScript/TypeScriptソースファイル
- CLI/APIオプション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ソースマップファイル | ファイル | .map拡張子のJSONファイル（external/linked時） |
| インラインソースマップ | Data URL | バンドルファイル末尾に埋め込み（inline時） |

### 出力先

ファイルシステム（external/linked）またはバンドルファイル内（inline）

## 処理フロー

### 処理シーケンス

```
1. 行オフセット計算
   └─ computeLineOffsets()で各ソースファイルの行オフセットを計算
2. コード生成時マッピング収集
   └─ コード出力時に元位置情報を記録
3. ソースマップピース結合
   └─ 各チャンクのソースマップピースを結合
4. VLQエンコード
   └─ マッピング情報をVLQ形式にエンコード
5. ソースマップ出力
   └─ 指定されたモードで出力（external/inline/linked）
```

### フローチャート

```mermaid
flowchart TD
    A[開始: ソースファイル] --> B[行オフセット計算]
    B --> C[コード生成]
    C --> D[マッピング情報収集]
    D --> E[VLQエンコード]
    E --> F{出力モード}
    F -->|external| G[.mapファイル生成]
    F -->|inline| H[Data URL埋め込み]
    F -->|linked| I[.mapファイル + リンクコメント]
    F -->|none| J[ソースマップなし]
    G --> K[終了]
    H --> K
    I --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-001 | external要件 | external指定時は--outdirが必須 | source_maps=external |
| BR-36-002 | linked形式 | バンドル末尾に//# sourceMappingURL=コメントを追加 | source_maps=linked |
| BR-36-003 | inline形式 | ソースマップをBase64エンコードしてData URLとして埋め込み | source_maps=inline |
| BR-36-004 | sourcesContent | 元ソースコードをソースマップに含める | デフォルト有効 |

### 計算ロジック

**VLQエンコーディング**: ソースマップのマッピング情報は、スペース効率のためVLQ（Variable Length Quantity）形式でエンコードされる。各マッピングは5つの値（生成行、生成列、ソースインデックス、元行、元列）をBase64 VLQで表現。

**行オフセットテーブル**: LineOffsetTable.generate()で各行の開始位置を事前計算し、マッピング時の高速な位置解決に使用。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | external指定でoutdir未指定 | --outdirを指定 |

### リトライ仕様

リトライは行わない。

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

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

## パフォーマンス要件

- 行オフセット計算とソースコンテンツ引用は並列処理で実行
- 大規模ファイルでも効率的に処理

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

- sourcesContentには元ソースコードが含まれるため、本番環境での公開に注意
- 機密情報を含むソースコードの場合、ソースマップの配布先を制限

## 備考

- debugIdオプションで一意のデバッグIDを付与可能
- DevServer使用時はインクリメンタルビルドに対応

---

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

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

### 推奨読解順序

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

まず、ソースマップで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sourcemap.zig | `src/sourcemap/sourcemap.zig` | SourceMap構造体、SourceMapState、ParseUrlResultHint |
| 1-2 | LinkerContext.zig | `src/bundler/LinkerContext.zig` | SourceMapData構造体、source_mapsオプション |

**読解のコツ**: SourceMapState構造体（8-18行目）がVLQエンコードの相対オフセット状態を管理。generated_line、generated_column、source_index、original_line、original_columnの5つの値を追跡。

#### Step 2: 行オフセット計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LinkerContext.zig | `src/bundler/LinkerContext.zig` | SourceMapData.computeLineOffsets()（132-154行目） |
| 2-2 | LinkerContext.zig | `src/bundler/LinkerContext.zig` | SourceMapData.computeQuotedSourceContents()（156-171行目） |

**主要処理フロー**:
- **132-154行目**: computeLineOffsets()で各ファイルの行オフセットテーブルを計算
- **156-171行目**: computeQuotedSourceContents()でsourcesContent用の引用を生成

#### Step 3: ソースマップ生成フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LinkerContext.zig | `src/bundler/LinkerContext.zig` | computeDataForSourceMap()（259-289行目） |

**主要処理フロー**:
- **264-267行目**: line_offset_tasks、quoted_contents_tasksの初期化
- **269-289行目**: 並列タスクのスケジューリング

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

```
BundleV2.bundle()
    │
    └─ LinkerContext
           ├─ computeDataForSourceMap()
           │      ├─ SourceMapData.Task.runLineOffset()
           │      │      └─ computeLineOffsets()
           │      │
           │      └─ SourceMapData.Task.runQuotedSourceContents()
           │             └─ computeQuotedSourceContents()
           │
           └─ generateChunksInParallel()
                  └─ ソースマップピース結合
                         └─ VLQエンコード
                                └─ ソースマップ出力
```

### データフロー図

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

ソースファイル ───▶ computeLineOffsets() ───▶ LineOffsetTable
       │
       ▼
ソースコード ────▶ computeQuotedSourceContents() ───▶ quotedContents
       │
       ▼
コード生成 ──────▶ マッピング情報収集 ───▶ SourceMapPieces
       │
       ▼
マッピング情報 ──▶ VLQエンコード ───▶ mappings文字列
       │
       ▼
全情報 ──────────▶ ソースマップJSON生成 ───▶ .mapファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sourcemap.zig | `src/sourcemap/sourcemap.zig` | ソース | ソースマップ構造、パース処理 |
| LinkerContext.zig | `src/bundler/LinkerContext.zig` | ソース | ソースマップデータ計算、並列処理 |
| Chunk.zig | `src/bundler/Chunk.zig` | ソース | output_source_mapフィールド |
| build_command.zig | `src/cli/build_command.zig` | ソース | --sourcemapオプション処理 |
| options.zig | `src/options.zig` | ソース | SourceMapOption定義 |
