# バッチ設計書 13-buildUtils

## 概要

本ドキュメントは、Jestリポジトリのビルドスクリプト群で共有されるユーティリティモジュール `buildUtils.mjs` の設計仕様を記載する。このモジュールは、パッケージ一覧取得、Webpack設定生成、著作権スニペット定義などの共通機能を提供する。

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

このモジュールは、Jestモノレポのビルドプロセス全体で使用される共通ユーティリティ関数群を提供するライブラリである。直接実行されるバッチではなく、他のビルドスクリプト（build.mjs、buildTs.mjs等）から参照される。

**業務上の目的・背景**：Jestは55以上のパッケージを持つ大規模モノレポであり、各パッケージのビルド処理には共通のロジックが多数存在する。このモジュールは、パッケージ一覧の取得、package.jsonの検証、Webpack設定の生成といった共通処理を一元化することで、ビルドスクリプトのメンテナンス性を向上させ、設定の一貫性を保証する。また、各パッケージのpackage.json構造を厳密に検証することで、リリース前に設定ミスを検出できる。

**バッチの実行タイミング**：このモジュール自体は直接実行されない。build.mjs、buildTs.mjs、bundleTs.mjsなどのビルドスクリプトからインポートされて使用される。

**主要な処理内容**：
1. packages/配下の全パッケージディレクトリを列挙し、package.jsonの存在確認
2. 各パッケージのpackage.json構造を検証（engines、exports、main、types等）
3. パッケージごとのWebpack設定オブジェクトを生成
4. 動的requireを無視するWebpackプラグイン（IgnoreDynamicRequire）を提供

**前後の処理との関連**：このモジュールはbuild.mjsから参照され、createWebpackConfigs関数でWebpack設定を生成する。また、buildTs.mjsからはgetPackagesWithTsConfig関数でTypeScript設定を持つパッケージ一覧を取得する。

**影響範囲**：このモジュールの変更はすべてのビルドスクリプトに影響する。特にpackage.json検証ロジックの変更は、ビルドの成功・失敗に直結する。

## バッチ種別

ユーティリティモジュール / ライブラリ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルド時（他スクリプトからの呼び出し） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 他のビルドスクリプトからのインポート |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.js環境 | Node.js 18.14.0以上、20.x、22.x、または24.x以上が必要 |
| 依存パッケージ | chalk、graceful-fs、read-pkg、webpack、webpack-node-externalsがインストール済み |
| babel.config.js | リポジトリルートにbabel.config.jsが存在すること |
| packages/ | packages/配下にパッケージディレクトリが存在すること |

### 実行可否判定

直接実行されるスクリプトではないため、実行可否判定は呼び出し元のスクリプトに依存する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 関数呼び出し時に引数を受け取る場合あり |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| packages/*/package.json | JSON | 各パッケージの設定ファイル |
| babel.config.js | JavaScript | Babel設定ファイル |
| package.json（ルート） | JSON | ルートパッケージの設定（engines.node参照） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| なし | - | ファイル出力は行わない（関数戻り値を返す） |

### 出力ファイル仕様

ファイル出力は行わない。各エクスポート関数の戻り値として設定オブジェクトやパッケージ情報を返す。

## 処理フロー

### 処理シーケンス

```
1. PACKAGES_DIR定数の初期化
   └─ import.meta.urlからpackages/ディレクトリの絶対パスを算出
2. getPackages関数
   └─ 2.1. packages/配下のディレクトリ一覧を取得
   └─ 2.2. 各ディレクトリのpackage.json存在確認
   └─ 2.3. package.jsonの内容を検証（engines、exports、main、types、bin）
   └─ 2.4. {packageDir, pkg}オブジェクトの配列を返却
3. getPackagesWithTsConfig関数
   └─ getPackagesの結果からtsconfig.jsonが存在するパッケージをフィルタ
4. createBuildConfigs関数
   └─ 4.1. getPackages()でパッケージ一覧取得
   └─ 4.2. 各パッケージのsrc/index.ts存在確認
   └─ 4.3. Babelオプションの設定（プラグイン追加含む）
   └─ 4.4. separateChunks（ワーカーファイル等）の設定
   └─ 4.5. extraEntryPoints（追加エントリポイント）の設定
   └─ 4.6. Webpack設定オブジェクトの生成
5. createWebpackConfigs関数
   └─ createBuildConfigsの結果からwebpackConfigのみを抽出
```

### フローチャート

```mermaid
flowchart TD
    A[モジュール読み込み] --> B[PACKAGES_DIR初期化]
    B --> C{getPackages呼び出し?}
    C -->|Yes| D[packages/配下スキャン]
    D --> E[各package.json読み込み]
    E --> F{検証成功?}
    F -->|No| G[アサーションエラー]
    F -->|Yes| H[パッケージ情報返却]
    C -->|No| I{createBuildConfigs呼び出し?}
    I -->|Yes| J[getPackages実行]
    J --> K[各パッケージのWebpack設定生成]
    K --> L[設定配列返却]
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | データベース操作は行わない |

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

データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | 検証エラー | package.jsonのenginesフィールドが存在しない | パッケージのpackage.jsonを修正 |
| AssertionError | 検証エラー | engines.nodeがルートと一致しない | 各パッケージのengines.nodeを統一 |
| AssertionError | 検証エラー | exportsフィールドが存在しないまたは不正 | exportsフィールドを正しく設定 |
| AssertionError | 検証エラー | main/typesフィールドが規定値と異なる | main="./build/index.js"、types="./build/index.d.ts"に設定 |
| Error | ファイル不在 | binに指定されたファイルが存在しない | binパスのファイルを作成 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | なし |
| リトライ対象エラー | なし |

### 障害時対応

このモジュールでエラーが発生した場合：
1. エラーメッセージを確認し、どのパッケージのどのフィールドに問題があるかを特定
2. 該当パッケージのpackage.jsonを修正
3. yarn constraintsで整合性を確認
4. ビルドを再実行

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし |
| コミットタイミング | なし |
| ロールバック条件 | なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 55以上のパッケージ |
| 目標処理時間 | 数秒以内（パッケージスキャン） |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

読み取り専用の処理のため、排他制御は不要。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| なし | - | ログ出力機能なし |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | - | 監視機能なし |

## 備考

### エクスポート一覧

| エクスポート名 | 種別 | 説明 |
|--------------|------|------|
| PACKAGES_DIR | 定数 | packages/ディレクトリの絶対パス |
| OK | 定数 | 成功表示用のchalk装飾文字列 |
| ERROR | 定数 | エラー表示用のchalk装飾文字列 |
| typeOnlyPackages | Set | 型定義のみのパッケージ名セット |
| INLINE_REQUIRE_EXCLUDE_LIST | 正規表現 | インラインrequire最適化の除外パターン |
| copyrightSnippet | 文字列 | Meta Platforms著作権ヘッダー |
| getPackagesWithTsConfig | 関数 | TypeScript設定を持つパッケージ一覧を取得 |
| createBuildConfigs | 関数 | パッケージごとのビルド設定を生成 |
| createWebpackConfigs | 関数 | Webpack設定オブジェクトの配列を生成 |

### IgnoreDynamicRequireプラグイン

Webpackで動的requireを無視するためのカスタムプラグイン。以下のケースでrequireを無視する：
- 引数が文字列でない場合
- 引数が相対パスでない場合（外部モジュール）
- separateChunksで指定されたファイルへのrequire
- require.resolveおよびrequire.resolve.paths

### typeOnlyPackages

以下のパッケージは型定義のみを提供するため、特別な扱いとなる：
- babel-preset-jest
- @jest/environment
- @jest/globals
- @jest/types
- @jest/test-globals
