# 機能設計書 39-依存関係解決

## 概要

本ドキュメントは、Bunパッケージマネージャーにおける依存関係解決（Dependency Resolution）機能の設計仕様を記載する。依存関係解決は、package.jsonに記述された依存パッケージを解析し、適切なバージョンを選択してインストールする機能である。

### 本機能の処理概要

依存関係解決機能は、プロジェクトのpackage.jsonに記述された依存関係を解析し、各パッケージの適切なバージョンを決定する。semver（セマンティックバージョニング）に基づくバージョン範囲の解決、依存関係ツリーの構築、競合の解決などを行う。

**業務上の目的・背景**：npmエコシステムでは、パッケージ間の依存関係が複雑に絡み合っている。同じパッケージでも異なるバージョンが要求されることがあり、これらを適切に解決してインストールすることが重要である。依存関係解決により、プロジェクトが正しく動作するために必要なすべてのパッケージを、互換性のあるバージョンでインストールできる。

**機能の利用シーン**：`bun install`実行時、`bun add`でパッケージ追加時、`bun update`でパッケージ更新時に利用される。

**主要な処理内容**：
1. package.jsonの依存関係パース
2. npmレジストリからのパッケージメタデータ取得
3. semverバージョン範囲の解決
4. 依存関係ツリーの構築
5. 依存関係の重複排除（deduplication）
6. ロックファイルへの記録

**関連システム・外部連携**：npmレジストリ、ロックファイル（bun.lockb/bun.lock）と連携。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | x (bunx) | 補助機能 | 未インストールパッケージの依存関係解決 |
| 6 | install | 主機能 | 依存関係ツリーの解決と最適化 |
| 7 | add | 主機能 | 追加パッケージの依存関係解決 |
| 9 | update | 主機能 | 更新バージョンの依存関係再解決 |
| 19 | why | 補助機能 | 依存関係ツリーの逆引き解析 |
| 22 | create | 補助機能 | テンプレート依存関係のインストール |

## 機能種別

計算処理 / データ解決

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dependencies | map | Yes | package.jsonのdependencies | パッケージ名 -> バージョン範囲 |
| devDependencies | map | No | 開発用依存関係 | パッケージ名 -> バージョン範囲 |
| optionalDependencies | map | No | オプション依存関係 | パッケージ名 -> バージョン範囲 |
| peerDependencies | map | No | ピア依存関係 | パッケージ名 -> バージョン範囲 |

### 入力データソース

- package.json
- npmレジストリ（パッケージメタデータ）
- 既存のロックファイル（存在する場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 解決済み依存関係 | Tree | パッケージID -> 解決済みバージョンのマッピング |
| ロックファイル | ファイル | 解決結果の永続化 |

### 出力先

メモリ内データ構造およびロックファイル

## 処理フロー

### 処理シーケンス

```
1. package.json読み込み
   └─ ルートパッケージの依存関係を抽出
2. ロックファイル読み込み（存在する場合）
   └─ 既存の解決結果を参照
3. パッケージメタデータ取得
   └─ npmレジストリから各パッケージの情報を取得
4. バージョン解決
   └─ semver範囲に合致する最新バージョンを選択
5. 依存関係展開
   └─ 選択したパッケージの依存関係を再帰的に解決
6. 重複排除
   └─ 互換性のあるバージョンを共有
7. ツリー構築
   └─ 最終的な依存関係ツリーを構築
8. ロックファイル更新
   └─ 解決結果を保存
```

### フローチャート

```mermaid
flowchart TD
    A[開始: package.json] --> B[依存関係抽出]
    B --> C{ロックファイル存在?}
    C -->|Yes| D[ロックファイル読み込み]
    C -->|No| E[新規解決開始]
    D --> F[差分チェック]
    F --> G{変更あり?}
    G -->|Yes| E
    G -->|No| H[キャッシュ利用]
    E --> I[npmレジストリクエリ]
    I --> J[バージョン解決]
    J --> K[依存関係展開]
    K --> L{未解決の依存あり?}
    L -->|Yes| I
    L -->|No| M[重複排除]
    M --> N[ツリー構築]
    H --> N
    N --> O[ロックファイル更新]
    O --> P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-001 | semver解決 | ^、~、>=などのsemver範囲を解釈 | バージョン指定時 |
| BR-39-002 | ロックファイル優先 | ロックファイルのバージョンを優先的に使用 | ロックファイル存在時 |
| BR-39-003 | 依存関係順序 | dependencies > devDependencies > optionalDependencies > peerDependencies | ソート時 |
| BR-39-004 | エイリアス対応 | npm:package@versionでエイリアスを解決 | エイリアス指定時 |

### 計算ロジック

**semverバージョン解決**: Dependency.Version構造体でバージョン範囲を表現。tag（npm, dist_tag, git, github, tarball等）に応じて異なる解決ロジックを適用。

**依存関係ソート**: Dependency.isLessThan()でソート順序を決定。behavior（依存関係タイプ）を優先し、次にパッケージ名でソート。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | パッケージ未検出 | パッケージ名を確認 |
| - | エラー | バージョン範囲に合致するバージョンなし | バージョン範囲を緩和 |
| - | 警告 | ピア依存関係未解決 | 必要に応じてインストール |

### リトライ仕様

ネットワークエラー時は自動リトライを行う。

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

ロックファイルの更新はアトミックに行われる。

## パフォーマンス要件

- 並列でパッケージメタデータを取得
- キャッシュを活用して重複リクエストを削減
- 大規模プロジェクトでも高速に解決

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

- パッケージの整合性チェック（integrity hash）
- 脆弱性スキャン（`bun audit`との連携）

## 備考

- ワークスペース（monorepo）での依存関係解決もサポート
- overridesによる強制バージョン指定が可能

---

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

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

### 推奨読解順序

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

まず、依存関係解決で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dependency.zig | `src/install/dependency.zig` | Dependency構造体、Version、Behavior |
| 1-2 | resolution.zig | `src/install/resolution.zig` | Resolution構造体、解決済みパッケージ情報 |

**読解のコツ**: Dependency構造体のname_hash、name、version、behaviorフィールドを理解する。Version.tag（npm, dist_tag, git等）で解決方法が変わる。

#### Step 2: 解決処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PackageManagerResolution.zig | `src/install/PackageManager/PackageManagerResolution.zig` | 解決処理のメイン関数 |

**主要処理フロー**:
- **1-34行目**: formatLaterVersionInCache()でキャッシュ内の最新バージョンチェック
- **80-139行目**: resolveFromDiskCache()でディスクキャッシュから解決
- **141-171行目**: assignResolution()で解決結果を割り当て
- **173-200行目**: verifyResolutions()で解決結果を検証

#### Step 3: ツリー構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Tree.zig | `src/install/lockfile/Tree.zig` | 依存関係ツリーの構造 |

**主要処理フロー**:
- 依存関係ツリーのノード構造
- 親子関係の管理

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

```
bun install
    │
    ├─ PackageManager.init()
    │      └─ package.json読み込み
    │
    ├─ Lockfile.load()
    │      └─ 既存ロックファイル読み込み
    │
    ├─ PackageManager.resolve()
    │      ├─ npmレジストリクエリ
    │      ├─ semverバージョン解決
    │      ├─ 依存関係展開
    │      └─ 重複排除
    │
    └─ Lockfile.save()
           └─ ロックファイル更新
```

### データフロー図

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

package.json ────▶ 依存関係抽出 ───▶ Dependency[]
       │
       ▼
ロックファイル ──▶ 既存解決参照 ───▶ キャッシュ
       │
       ▼
npmレジストリ ───▶ メタデータ取得 ───▶ PackageManifest
       │
       ▼
バージョン範囲 ──▶ semver解決 ───▶ 具体的バージョン
       │
       ▼
依存関係ツリー ──▶ 重複排除 ───▶ 最適化ツリー
       │
       ▼
解決結果 ────────▶ Lockfile.save() ───▶ ロックファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dependency.zig | `src/install/dependency.zig` | ソース | Dependency構造体定義 |
| resolution.zig | `src/install/resolution.zig` | ソース | Resolution構造体定義 |
| PackageManagerResolution.zig | `src/install/PackageManager/PackageManagerResolution.zig` | ソース | 解決処理 |
| PackageManager.zig | `src/install/PackageManager.zig` | ソース | パッケージマネージャー本体 |
| Tree.zig | `src/install/lockfile/Tree.zig` | ソース | 依存関係ツリー |
| lockfile.zig | `src/install/lockfile.zig` | ソース | ロックファイル処理 |
| npm.zig | `src/install/npm.zig` | ソース | npmレジストリ通信 |
