# バッチ設計書 1-bin/webpack.js

## 概要

本ドキュメントは、webpackのCLIエントリポイントスクリプト `bin/webpack.js` の設計仕様を定義するものである。このスクリプトはwebpackコマンドの実行開始時に呼び出され、webpack-cliパッケージの存在確認とCLI起動を担う。

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

`bin/webpack.js` は、ユーザーがコマンドラインから `webpack` コマンドを実行した際に最初に呼び出されるエントリポイントスクリプトである。webpack-cliパッケージの有無を確認し、インストール済みであればCLIを直接起動する。未インストールの場合はユーザーに対話的にインストールを促し、承諾された場合は自動的にインストールを実行した上でCLIを起動する。

**業務上の目的・背景**：webpackはコアライブラリとCLIツールが分離されたアーキテクチャを採用しており、webpack-cliがインストールされていない環境でもユーザーフレンドリーな案内を提供する必要がある。このスクリプトは、webpackのインストール直後にCLIが未導入の状態でも、スムーズにCLI環境をセットアップできるようにするための橋渡し役を担っている。

**バッチの実行タイミング**：ユーザーがターミナルで `webpack` コマンド（または `npx webpack`）を実行するたびに起動される。手動実行・CI/CDパイプラインの双方で利用される。

**主要な処理内容**：
1. webpack-cliパッケージのインストール状態を確認する（ローカル・グローバルの双方を探索）
2. インストール済みの場合はCLIのバイナリを特定してロード・実行する（ESM/CJS両対応）
3. 未インストールの場合はパッケージマネージャを自動検出し（yarn/pnpm/npm）、ユーザーに対話的にインストール確認を行う
4. インストール承諾後、検出したパッケージマネージャでwebpack-cliをdevDependencyとしてインストールする
5. インストール完了後にCLIを起動する

**前後の処理との関連**：このスクリプトはpackage.jsonのbinフィールドに `"webpack": "bin/webpack.js"` として登録されており、npmパッケージインストール後にシステムパスに配置される。後続処理としてwebpack-cliの各種サブコマンド（build、serve、configtest等）が実行される。

**影響範囲**：webpackコマンドを利用する全てのユーザー環境に影響する。パッケージマネージャの自動検出はプロジェクトルートのロックファイル（yarn.lock / pnpm-lock.yaml）を参照するため、プロジェクトの設定状況にも依存する。

## バッチ種別

CLI起動 / 環境セットアップ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動（webpackコマンド実行時） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.jsランタイム | Node.js 10.13.0以上がインストールされていること |
| webpackパッケージ | webpackがnpmパッケージとしてインストールされていること |
| graceful-fsパッケージ | webpackの依存関係としてインストール済みであること |

### 実行可否判定

特別な実行可否判定ロジックはない。`webpack` コマンドが呼び出された時点で無条件に実行される。webpack-cliの有無に応じて処理フローが分岐する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| （CLIコマンド引数） | string[] | No | なし | webpack-cliに引き渡されるコマンドライン引数。本スクリプト自体は直接利用しない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| node_modules/webpack-cli | ディレクトリ | webpack-cliパッケージの存在確認対象 |
| yarn.lock | ファイル | パッケージマネージャ自動検出用（yarn判定） |
| pnpm-lock.yaml | ファイル | パッケージマネージャ自動検出用（pnpm判定） |
| webpack-cli/package.json | JSON | CLIバイナリのパス解決用 |
| process.versions.pnp | ランタイム情報 | Yarn PnP環境の検出用 |
| module.globalPaths | ランタイム情報 | グローバルインストールパスの探索用 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力（stdout） | テキスト | インストール進捗メッセージ |
| 標準エラー出力（stderr） | テキスト | エラーメッセージ、インストール案内 |
| process.exitCode | 数値 | 0: 正常終了、1: エラー終了 |

### 出力ファイル仕様

本スクリプト自体はファイル出力を行わない。webpack-cliのインストール処理が実行された場合、パッケージマネージャによりnode_modulesディレクトリが更新される。

## 処理フロー

### 処理シーケンス

```
1. isInstalled("webpack-cli") でインストール状態を確認
   └─ __dirnameから親ディレクトリを遡りnode_modules/webpack-cliの存在をチェック
   └─ Yarn PnP環境の場合はtrueを即座に返却
   └─ module.globalPathsのグローバルパスも探索
2. インストール済みの場合
   └─ runCli(cli) を実行
   └─ webpack-cli/package.jsonからバイナリパスを解決
   └─ ESMモジュール（.mjs / type: "module"）の場合はdynamic importで読み込み
   └─ CJSモジュールの場合はrequireで読み込み
3. 未インストールの場合
   └─ パッケージマネージャの自動検出（yarn.lock → yarn、pnpm-lock.yaml → pnpm、それ以外 → npm）
   └─ readlineインターフェースでユーザーに確認プロンプトを表示
   └─ "yes" 応答の場合: パッケージマネージャでwebpack-cliをdevDependencyとしてインストール
   └─ インストール成功後にrunCli(cli)を実行
   └─ "no" 応答の場合: 手動インストールの案内を表示して終了（exitCode: 1）
   └─ STDIN非対話モードの場合: コールバック未実行のままexitCode: 1で終了
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{Yarn PnP環境?}
    B -->|Yes| C[webpack-cliインストール済みとみなす]
    B -->|No| D[ローカルnode_modules探索]
    D --> E{webpack-cli発見?}
    E -->|Yes| C
    E -->|No| F[グローバルパス探索]
    F --> G{webpack-cli発見?}
    G -->|Yes| C
    G -->|No| H[未インストール]
    C --> I[runCli: package.jsonからバイナリパス解決]
    I --> J{ESMモジュール?}
    J -->|Yes| K[dynamic importで読み込み]
    J -->|No| L[requireで読み込み]
    K --> M[バッチ終了]
    L --> M
    H --> N[パッケージマネージャ自動検出]
    N --> O[ユーザーにインストール確認]
    O --> P{ユーザー応答}
    P -->|Yes| Q[webpack-cliインストール実行]
    Q --> R{インストール成功?}
    R -->|Yes| I
    R -->|No| S[エラー出力, exitCode=1]
    P -->|No| T[手動インストール案内, exitCode=1]
    S --> M
    T --> M
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| exitCode=1 | パッケージ未インストール | webpack-cliが未インストールでユーザーがインストールを拒否 | webpack-cliを手動でインストールする |
| exitCode=1 | インストール失敗 | パッケージマネージャによるインストールが失敗 | ネットワーク接続・npm registry設定を確認する |
| exitCode=1 | CLI読み込みエラー | webpack-cliのバイナリの読み込みに失敗（dynamic import失敗等） | webpack-cliの再インストールを行う |
| exitCode=1 | 非対話モード | STDINがターミナルモードでない場合にreadlineコールバックが実行されない | CI環境等ではwebpack-cliを事前にインストールしておく |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（リトライ機構は未実装） |

### 障害時対応

webpack-cliのインストールに失敗した場合は、手動で `npm install -D webpack-cli`（または対応するパッケージマネージャのコマンド）を実行して再度webpackコマンドを実行する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（データベース操作なし） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回の実行で1つのCLI起動 |
| 目標処理時間 | webpack-cliインストール済みの場合は数百ミリ秒以内。未インストールの場合はパッケージインストール時間に依存 |
| メモリ使用量上限 | 特に制限なし（Node.jsデフォルト） |

## 排他制御

排他制御は行わない。同一プロジェクトで同時にwebpackコマンドを複数実行することは可能だが、webpack-cliのインストール処理が同時に走った場合はパッケージマネージャのロック機構に依存する。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 案内ログ | webpack-cli未インストール検出時 | CLIインストールが必要である旨とwebpack-cliのURL |
| インストール案内ログ | パッケージマネージャ検出後 | 使用するパッケージマネージャとインストールコマンド |
| インストール開始ログ | ユーザー承認後 | インストール実行中のメッセージ |
| エラーログ | エラー発生時 | エラー詳細（インストール失敗、CLI読み込みエラー等） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| N/A | N/A | N/A（監視設定は未実装） |

## 備考

- package.jsonの `bin` フィールドで `"webpack": "bin/webpack.js"` として登録されており、npmインストール時にシステムパスにシンボリックリンクが作成される
- Yarn PnP（Plug'n'Play）環境ではnode_modules探索をスキップし、常にインストール済みと判定する
- ESMモジュール対応として、webpack-cliのpackage.jsonの `type` フィールドまたはバイナリファイルの拡張子（.mjs）を判定してimport方式を切り替える
- child_processのspawnは `shell: true` オプション付きで実行されるため、OSのシェルを経由してコマンドが実行される
- process.exitCodeを事前に1に設定し、正常フロー時のみ0にリセットする防御的な実装パターンを採用している
