# 機能設計書 79-コマンドラインインターフェース

## 概要

本ドキュメントは、webpackのCLIからのコマンド実行・オプション解析・設定ファイル読み込み機能について、そのエントリーポイント・CLI引数の解析ロジック・webpack-cliとの連携を詳細に記述した機能設計書である。

### 本機能の処理概要

コマンドラインインターフェース機能は、`webpack`コマンドの実行エントリーポイント（bin/webpack.js）とJSON Schemaベースの CLI引数解析ライブラリ（lib/cli.js）の2つの要素で構成される。

**業務上の目的・背景**：webpackはCLIからの実行が主要なユースケースの一つであり、設定ファイルなしでもCLI引数によるビルド設定を可能にする必要がある。bin/webpack.jsはwebpack-cliパッケージへのブートストラッパーとして機能し、lib/cli.jsはwebpack設定スキーマからCLI引数を自動生成する機能を提供する。

**機能の利用シーン**：ターミナルからの`npx webpack`コマンド実行。CI/CDパイプラインでのビルドスクリプト。webpack-cliを通じたCLI引数からのwebpack設定構築。

**主要な処理内容**：
1. bin/webpack.js: webpack-cliの存在確認とブートストラップ
2. bin/webpack.js: webpack-cli未インストール時の自動インストール案内
3. lib/cli.js: WebpackOptions JSONスキーマからCLI引数（Flags）の自動生成
4. lib/cli.js: スキーマ解析によるオプションパスからCLI引数名への変換
5. lib/cli.js: CLI引数値のwebpack設定オブジェクトへの変換・適用

**関連システム・外部連携**：webpack-cliパッケージ。yarn/pnpm/npmパッケージマネージャー。WebpackOptions.json スキーマ。

**権限による制御**：本機能に権限による制御はない。

## 関連画面

本機能に直接関連する画面はない。CLIターミナルが操作インターフェースとなる。

## 機能種別

CLIインターフェース・オプション解析

## 入力仕様

### 入力パラメータ

bin/webpack.js: パラメータなし（process.argvはwebpack-cliが処理）

lib/cli.js getArguments関数:

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| schema | Schema | No | JSONスキーマ | デフォルト: WebpackOptions.json |

### 入力データソース

- process.argv（CLIコマンドライン引数）
- schemas/WebpackOptions.json（CLIフラグ自動生成用）
- ファイルシステム（yarn.lock、pnpm-lock.yaml検出）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Flags | Record<string, Argument> | CLI引数名をキーとし、型情報・説明・設定パスを含むArgumentオブジェクトを値とするマップ |

### 出力先

webpack-cliが消費する引数定義情報。

## 処理フロー

### 処理シーケンス

```
bin/webpack.js:
1. webpack-cliのインストール確認
   ├─ isInstalled("webpack-cli")
   │   ├─ process.versions.pnp確認（Yarn PnP）
   │   ├─ ローカルnode_modules走査
   │   └─ グローバルglobalPaths走査
   ├─ [インストール済み] → runCli(cli)
   │   ├─ package.jsonのtype/bin情報を読み取り
   │   ├─ ESM(type:"module")の場合はimport()で読み込み
   │   └─ CJSの場合はrequire()で読み込み
   └─ [未インストール] → インストールプロンプト
       ├─ パッケージマネージャー判定（yarn.lock/pnpm-lock.yaml）
       ├─ ユーザーに確認（readlineインターフェース）
       └─ 承認時: npm/yarn/pnpm install -D webpack-cli → runCli

lib/cli.js:
1. getArguments(schema)
   ├─ WebpackOptions.jsonスキーマの解析
   ├─ pathToArgumentName: 設定パス→CLI引数名変換
   │   └─ ドット区切り→ハイフン区切り、CamelCase→kebab-case
   ├─ traverse: スキーマの再帰的走査
   │   ├─ $ref解決
   │   ├─ cli.excludeフラグによる除外
   │   ├─ anyOf/oneOf/allOfの展開
   │   └─ enum/string/number/boolean/RegExpの型判定
   ├─ addFlag: 引数定義の追加
   └─ addResetFlag: 配列リセット用フラグの追加
2. processArguments: CLI引数値の設定オブジェクトへの適用
```

### フローチャート

```mermaid
flowchart TD
    A[webpack コマンド実行] --> B{webpack-cli インストール済み?}
    B -->|Yes| C[runCli]
    B -->|No| D[パッケージマネージャー判定]
    D --> E[インストール確認プロンプト]
    E -->|Yes| F[webpack-cli インストール]
    E -->|No| G[エラーメッセージ表示]
    F --> C
    C --> H{package.json type?}
    H -->|module| I[import で読み込み]
    H -->|commonjs| J[require で読み込み]
    I --> K[webpack-cli 実行]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-79-01 | webpack-cli必須 | webpackのCLI実行にはwebpack-cliパッケージが必要 | bin/webpack.js実行時 |
| BR-79-02 | パッケージマネージャー自動検出 | yarn.lock→yarn、pnpm-lock.yaml→pnpm、その他→npm | webpack-cli未インストール時 |
| BR-79-03 | ESM/CJS自動判定 | package.jsonのtypeフィールドとbinファイルの拡張子でESM/CJSを判定 | runCli実行時 |
| BR-79-04 | 引数名変換 | 設定パスのドット区切りをハイフン区切りに変換し、CamelCaseをkebab-caseに変換 | getArguments時 |
| BR-79-05 | cli.exclude除外 | スキーマのcli.excludeフラグがtrueのプロパティはCLI引数から除外 | getArguments時 |
| BR-79-06 | resetフラグ | 配列型プロパティには自動的にリセットフラグ（--xxx-reset）が追加される | getArguments時 |
| BR-79-07 | 非対話エラー | STDINが非対話モードの場合、インストール確認なしでexit code 1で終了 | webpack-cli未インストール時 |

### 計算ロジック

pathToArgumentName変換:
- `output.filename` → `output-filename`
- `module.rules[].use` → `module-rules-use`
- `optimization.splitChunks` → `optimization-split-chunks`

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

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| exit code 1 | プロセスエラー | webpack-cli未インストールかつユーザーがインストール拒否 | webpack-cliを手動インストール |
| exit code 1 | プロセスエラー | webpack-cliのインストールコマンド失敗 | ネットワーク/権限を確認し手動インストール |

### リトライ仕様

webpack-cliインストール失敗時はリトライしない。ユーザーが手動で再実行する。

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

トランザクション管理は不要。

## パフォーマンス要件

bin/webpack.jsはブートストラッパーであり、実質的な処理はwebpack-cliに委譲される。lib/cli.jsのgetArgumentsはスキーマの再帰的走査を行うが、起動時に一度だけ実行されるため性能問題はない。

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

- webpack-cliの自動インストール機能はユーザー承認を必須とする
- child_process.spawnによるインストールコマンド実行はstdio: "inherit"で透明性を確保

## 備考

- bin/webpack.jsはwebpackパッケージのエントリーポイント（package.jsonのbinフィールド）
- lib/cli.jsはwebpack-cliから参照される引数定義生成ユーティリティ
- Yarn PnP環境ではisInstalled関数がprocess.versions.pnpをチェックしtrueを返す

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli.js | `lib/cli.js` | Flags型、Argument型、ArgumentConfig型の定義 |

**読解のコツ**: lib/cli.jsの先頭にJSDocによる型定義がある。PathItem、ProblemType、Value、Argument等の型を先に把握すると、後続の処理が理解しやすい。

#### Step 2: ブートストラッパー

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | webpack.js | `bin/webpack.js` | webpack-cliのブートストラップ処理 |

**主要処理フロー**:
1. **10-31行目**: runCommand関数（child_process.spawnによるコマンド実行）
2. **37-75行目**: isInstalled関数（webpack-cliの存在確認）
3. **81-98行目**: runCli関数（ESM/CJS判定とwebpack-cli実行）
4. **111-117行目**: cli定義オブジェクト
5. **119-196行目**: メイン処理（インストール確認・自動インストール）

#### Step 3: CLI引数生成

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cli.js | `lib/cli.js` | getArguments関数のスキーマ走査ロジック |

**主要処理フロー**:
- **78行目**: getArguments関数エントリーポイント
- **86-95行目**: pathToArgumentName変換ロジック
- **290行目**: traverse関数（スキーマの再帰的走査）
- **196-219行目**: addResetFlag関数
- **226-279行目**: addFlag関数

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

```
$ npx webpack
    |
    +-- bin/webpack.js
            |
            +-- isInstalled("webpack-cli")
            |       +-- process.versions.pnp チェック
            |       +-- ローカル node_modules 走査
            |       +-- グローバル globalPaths 走査
            |
            +-- [インストール済み] runCli(cli)
            |       +-- require.resolve("webpack-cli/package.json")
            |       +-- import() or require() → webpack-cli実行
            |
            +-- [未インストール] インストールプロンプト
                    +-- fs.existsSync("yarn.lock" / "pnpm-lock.yaml")
                    +-- readline.createInterface()
                    +-- runCommand(packageManager, install args)
                    +-- runCli(cli)

webpack-cli
    |
    +-- require("webpack/lib/cli").getArguments()
            +-- traverse(schema)
                    +-- addFlag() / addResetFlag()
```

### データフロー図

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

$ npx webpack             bin/webpack.js
  (CLI引数) -----------> isInstalled() ----+
                                           |
                         [未インストール]    |
                         readLine ----------|---> webpack-cliインストール
                                           |
                         [インストール済み]   |
                         runCli() ---------+---> webpack-cli起動

schemas/                 lib/cli.js
  WebpackOptions.json -> getArguments() --------> Flags (引数定義)
                              |
                              v
                         traverse(schema)
                         pathToArgumentName()
                         addFlag()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| webpack.js | `bin/webpack.js` | ソース | CLIエントリーポイント・webpack-cliブートストラッパー |
| cli.js | `lib/cli.js` | ソース | CLI引数定義生成・設定適用ユーティリティ |
| WebpackOptions.json | `schemas/WebpackOptions.json` | スキーマ | CLI引数生成のソーススキーマ |
| webpack-cli | `node_modules/webpack-cli/` | 外部依存 | 実際のCLI処理を担当 |
