# バッチ設計書 22-scripts/webpack.js

## 概要

本ドキュメントは、Decap CMSプロジェクトにおける各パッケージ共通のWebpackビルド設定を提供するスクリプト `scripts/webpack.js` の設計を記述する。

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

本スクリプトは、Decap CMSモノレポ内の各パッケージがWebpackビルドを実行する際に利用する共通設定（ルール、プラグイン、出力先、externals等）を提供するNode.jsモジュールである。UMD形式およびCJS形式のビルド出力に対応し、本番環境・開発環境の切り替えを自動で行う。

**業務上の目的・背景**：Decap CMSは38以上のパッケージで構成されるモノレポであり、各パッケージが個別にWebpack設定を管理すると設定の重複・不整合が発生する。本スクリプトにより共通ビルド設定を一元管理し、全パッケージで一貫したビルド出力を実現する。babel-loader、css-loader、svg-inline-loader等のルール設定、IgnorePlugin・FriendlyErrorsPlugin・ProvidePlugin等のプラグイン設定、UMD/CJS出力先設定を統合的に提供する。

**バッチの実行タイミング**：各パッケージの `webpack.config.js` から `require('../../scripts/webpack.js')` で読み込まれ、`npm run build` や `nx run-many -t build` 実行時に間接的に実行される。

**主要な処理内容**：
1. Babel/CSS/SVG/vfileの4種類のWebpackローダールール定義
2. IgnorePlugin（esprima除外）、FriendlyErrorsWebpackPlugin、ProvidePlugin（Buffer）の3種類のプラグイン定義
3. UMD/UMDdir/CJSの3種類の出力ターゲット設定
4. ピア依存関係に基づくexternals設定（UMDとCJSで異なるロジック）
5. `getConfig` 関数による統合設定オブジェクトの提供

**前後の処理との関連**：本スクリプトは `scripts/externals.js` からexternalsマッピングと `toGlobalName` 関数をインポートする。各パッケージの `webpack.config.js`（例：`packages/decap-cms-core/webpack.config.js`）が `getConfig` を呼び出して利用する。`npm run build`（`nx run-many -t build`）の実行チェインの中核を担う。

**影響範囲**：全パッケージのWebpackビルド出力に直接影響する。ルールやプラグインの変更は全パッケージのバンドル内容に波及する。

## バッチ種別

ビルドユーティリティ（Webpack共通ビルド設定モジュール）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（Webpackビルド実行時に自動読み込み） |
| 実行時刻 | N/A |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 各パッケージの `webpack.config.js` からの `require` 呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.js実行環境 | Node.jsが利用可能であること |
| npm依存関係のインストール | webpack, @soda/friendly-errors-webpack-plugin, lodash, babel-loader, css-loader等がインストール済みであること |
| scripts/externals.js | externalsマッピングが正しく生成されること |
| package.json | 実行ディレクトリにpackage.jsonが存在し、peerDependenciesが定義されていること |

### 実行可否判定

本モジュールは `require` で読み込まれた時点で即座にモジュールレベルコードが実行される。`process.cwd()` のpackage.jsonが存在しない場合、読み込みに失敗する。また、peerDependenciesに記載されたパッケージが `scripts/externals.js` のexternalsに定義されていない場合、例外がスローされる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| target | string | No | 本番: `'umd'` / 開発: `'umddir'` | `baseConfig` 関数のオプション。出力ターゲットを指定 |
| baseOnly | boolean | No | `false` | `getConfig` 関数のオプション。trueの場合、配列ではなく単一設定オブジェクトを返す |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| `process.cwd()/package.json` | JSON | 実行パッケージのpackage.json。name, peerDependenciesを参照 |
| `scripts/externals.js` | Node.jsモジュール | externalsマッピングとtoGlobalName関数 |
| `NODE_ENV` 環境変数 | 文字列 | `'production'` または `'test'` で動作を切り替え |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| `module.exports.getConfig` | JavaScript関数 | Webpack設定オブジェクト（またはその配列）を返す関数 |
| `module.exports.rules` | JavaScriptオブジェクト | js/css/svg/vfileのWebpackルール定義 |
| `module.exports.plugins` | JavaScriptオブジェクト | ignoreEsprima/friendlyErrors/bufferのプラグイン定義 |

### 出力ファイル仕様

本モジュールはファイル出力を行わない。Webpackビルド実行時に設定オブジェクトとして利用され、Webpackがバンドルファイルを出力する。

| 項目 | 内容 |
|-----|------|
| UMD出力先 | `{パッケージdir}/dist/{パッケージ名}.js` |
| UMDdir出力先 | `{パッケージdir}/dist/umd/index.js` |
| CJS出力先 | `{パッケージdir}/dist/cjs/index.js` |
| 文字コード | UTF-8 |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 依存モジュールの読み込み
   └─ webpack, FriendlyErrorsWebpackPlugin, lodash, externals.js, package.json
2. 環境変数の判定
   └─ NODE_ENV から isProduction / isTest フラグを設定
3. ルール定義（rules関数）
   ├─ js: babel-loader（ts/tsx/js/jsx対応、node_modules除外）
   ├─ css: css-loader（ol/react-toastify/codemirror向け）
   ├─ svg: svg-inline-loader（node_modules除外）
   └─ vfile: imports-loader（process/browser polyfill）
4. プラグイン定義（plugins関数）
   ├─ ignoreEsprima: IgnorePlugin（esprima除外）
   ├─ friendlyErrors: FriendlyErrorsWebpackPlugin
   └─ buffer: ProvidePlugin（Buffer polyfill）
5. 出力ターゲット定義（targetOutputs関数）
   ├─ umd: dist/{パッケージ名}.js（UMD形式、libraryTarget: 'umd'）
   ├─ umddir: dist/umd/index.js（UMD形式、開発用）
   └─ cjs: dist/cjs/index.js（libraryTarget: 'window'）
6. externals設定
   ├─ UMDターゲット: peerDependenciesをexternals.jsのマッピングで解決
   └─ CJSターゲット: peerDependenciesを正規表現でマッチング
7. baseConfig関数で全設定を統合
8. getConfig関数でエクスポート
```

### フローチャート

```mermaid
flowchart TD
    A[モジュール読み込み] --> B[環境変数判定]
    B --> C[externals.jsインポート]
    C --> D[package.jsonインポート]
    D --> E{getConfig呼び出し}
    E -->|baseOnly=true| F[単一UMD設定を返却]
    E -->|baseOnly=false| G[UMD設定の配列を返却]
    F --> H[baseConfig生成]
    G --> H
    H --> I[ルール適用: js/css/svg/vfile]
    I --> J[プラグイン適用: ignoreEsprima/friendlyErrors/buffer]
    J --> K{ターゲット判定}
    K -->|umd/umddir| L[UMD externals適用]
    K -->|cjs| M[CJS externals適用]
    L --> N[設定オブジェクト返却]
    M --> N
```

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

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

本スクリプトはデータベース操作を行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

N/A

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 外部依存不足エラー | peerDependenciesのパッケージがexternalsに未定義 | `scripts/externals.js` にexternals定義を追加する |
| N/A | モジュール読み込みエラー | package.jsonが存在しない | 正しいパッケージディレクトリから実行する |
| N/A | 依存パッケージ不足 | webpack等のdevDependenciesが未インストール | `npm install` を実行する |

### リトライ仕様

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

### 障害時対応

本モジュールの読み込みまたは設定生成に失敗した場合、Webpackビルド全体が失敗する。エラーメッセージを確認し、externalsの未定義パッケージの追加やdevDependenciesのインストールを行う。

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 全パッケージのWebpackビルド（約38パッケージ） |
| 目標処理時間 | 設定生成自体は即座（Webpackビルド全体は数分） |
| メモリ使用量上限 | Webpackビルドプロセスに依存 |

## 排他制御

排他制御は不要。各パッケージのビルドはNxにより並列実行される可能性があるが、本モジュール自体は読み取り専用の設定提供であるため競合は発生しない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| ビルド情報 | targetOutputs実行時 | `Building [{パッケージ名}, library: {グローバル名}]` |
| Webpack統計 | ビルド完了時 | stats設定に基づく（本番: 最小限、開発: all false） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ビルド成否 | N/A | CI/CDパイプライン（GitHub Actions） |
| externals不足エラー | 1件以上 | ビルドログ（コンソール出力） |

## 備考

- 本番環境（`NODE_ENV=production`）ではUMDターゲット、開発環境ではUMDdirターゲットがデフォルトとなる
- CJSターゲットのlibraryTargetが `'window'` に設定されている点は意図的な設定である可能性がある
- `getConfig({ baseOnly: true })` はdecap-cmsパッケージのビルド用に単一設定を返す
- babel-loaderは `rootMode: 'upward'` で実行され、プロジェクトルートのBabel設定を参照する
- CSS loaderはol（OpenLayers）、react-toastify、codemirrorのnode_modulesのみを対象とする
- source-mapはテスト環境以外で生成される
- resolve.extensionsに `.ts`, `.tsx`, `.js`, `.json` が設定されている
- stream-browserifyがfallbackとして設定されている
