# バッチ設計書 21-scripts/externals.js

## 概要

本ドキュメントは、Decap CMSプロジェクトにおけるWebpackビルド用の外部依存関係マッピング生成スクリプト `scripts/externals.js` の設計を記述する。

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

本スクリプトは、Decap CMSのモノレポ内の全パッケージおよび主要サードパーティライブラリについて、Webpackの `externals` 設定に必要なマッピング情報を生成する。パッケージ名をUMDグローバル名に変換し、各モジュール形式（UMD/CommonJS/CommonJS2/AMD）向けのエクスポート定義を提供する。

**業務上の目的・背景**：Decap CMSはモノレポ構成で多数のパッケージを管理しており、各パッケージをWebpackでビルドする際にピア依存関係をバンドルに含めないようにする必要がある。本スクリプトはパッケージ名からUMDグローバル名への変換ロジックを一元管理し、ビルド設定の一貫性と保守性を確保する。

**バッチの実行タイミング**：本スクリプトはNode.jsモジュールとして `scripts/webpack.js` から `require` で読み込まれるため、Webpackビルド実行時（`npm run build` 等）に間接的に実行される。単体での定期実行やスケジュール実行は行わない。

**主要な処理内容**：
1. `toGlobalName` 関数によるパッケージ名のキャメルケース変換（例：`decap-cms-core` を `DecapCmsCore` に変換）
2. `packages/` ディレクトリ配下の全パッケージを走査し、各パッケージのexternals定義を自動生成
3. lodash、@emotion/react、@emotion/styled、react、react-dom等の主要サードパーティライブラリのexternals定義を静的に定義
4. 上記をマージした `externals` オブジェクトと `toGlobalName` 関数をエクスポート

**前後の処理との関連**：本スクリプトは `scripts/webpack.js` から参照され、各パッケージの `webpack.config.js` が `scripts/webpack.js` の `getConfig` を呼び出す際に間接的に利用される。ビルドパイプラインの基盤となるモジュールである。

**影響範囲**：全パッケージのWebpackビルド設定に影響する。externalsマッピングが不正な場合、UMDバンドルの依存関係解決が失敗し、ブラウザ上でのランタイムエラーの原因となる。

## バッチ種別

ビルドユーティリティ（Webpackビルド設定の外部依存関係マッピング生成モジュール）

## 実行スケジュール

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

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.js実行環境 | Node.jsが利用可能であること |
| パッケージディレクトリの存在 | `packages/` ディレクトリが存在し、各パッケージのサブディレクトリが配置されていること |
| fsモジュール | Node.js標準の `fs` モジュールが利用可能であること |

### 実行可否判定

本モジュールは `require` で読み込まれた時点で即座に実行される。`packages/` ディレクトリが存在しない場合、`fs.readdirSync` が例外をスローする。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| N/A | - | - | - | 本モジュールは入力パラメータを受け取らない。`require` 時に自動実行される |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| `packages/` ディレクトリ | ファイルシステム | モノレポ内の全パッケージ名を取得するために走査 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| `module.exports.externals` | JavaScriptオブジェクト | Webpack externals設定用の依存関係マッピング |
| `module.exports.toGlobalName` | JavaScript関数 | パッケージ名をUMDグローバル名に変換する関数 |

### 出力ファイル仕様

本モジュールはファイル出力を行わない。`module.exports` でオブジェクトと関数をエクスポートする。

| 項目 | 内容 |
|-----|------|
| ファイル名 | N/A（モジュールエクスポート） |
| 出力先 | N/A |
| 文字コード | UTF-8 |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. toGlobalName関数の定義
   └─ ダッシュ区切りのパッケージ名をPascalCaseに変換するユーティリティ関数
2. packagesディレクトリの走査
   └─ fs.readdirSync で packages/ 配下の全ディレクトリ名を取得
3. パッケージごとのexternals定義生成
   └─ 各パッケージ名に対して root/commonjs2/commonjs/amd/umd の5形式のマッピングを生成
4. サードパーティライブラリのexternals定義を静的に追加
   └─ lodash, @emotion/react, @emotion/styled, codemirror, immutable, prop-types,
      react-immutable-proptypes, react, react-dom, uuid
5. エクスポート
   └─ externals オブジェクトと toGlobalName 関数を module.exports で公開
```

### フローチャート

```mermaid
flowchart TD
    A[モジュール読み込み開始] --> B[toGlobalName関数定義]
    B --> C[packages/ディレクトリ走査]
    C --> D[パッケージ名ごとにexternals定義生成]
    D --> E[サードパーティライブラリの静的externals定義を追加]
    E --> F[externalsオブジェクトとtoGlobalNameをエクスポート]
    F --> G[モジュール読み込み完了]
```

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

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

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

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

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

N/A

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | ファイルシステムエラー | `packages/` ディレクトリが存在しない | プロジェクトルートからの実行を確認する |
| N/A | 参照エラー | `path` または `fs` モジュールが利用不可 | Node.js環境を確認する |

### リトライ仕様

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

### 障害時対応

本モジュールの読み込みに失敗した場合、Webpackビルド全体が失敗する。`packages/` ディレクトリの存在とプロジェクト構造が正しいことを確認する。

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | packages/ 配下の全パッケージ数（約38パッケージ） |
| 目標処理時間 | 100ms以下（同期的ファイルシステム操作のため即座に完了） |
| メモリ使用量上限 | 最小限（オブジェクトマッピングのみ） |

## 排他制御

排他制御は不要。モジュール読み込み時にNode.jsのモジュールキャッシュにより一度だけ実行され、以降はキャッシュされた結果が返される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| N/A | N/A | 本モジュールはログ出力を行わない |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| N/A | N/A | 本モジュール単体での監視は不要。Webpackビルドの成否で間接的に検知される |

## 備考

- `toGlobalName` 関数の変換例：`decap-cms-core` → `DecapCmsCore`、`decap-cms-widget-markdown` → `DecapCmsWidgetMarkdown`
- サードパーティライブラリの一部（lodash, immutable, prop-types等）は `DecapCmsDefaultExports` オブジェクト配下にグローバル名が配置される
- react と react-dom は独立したグローバル名（`React`, `ReactDOM`）を持つ
- codemirror は独立したグローバル名（`CodeMirror`）を持つ
