# 画面設計書 1-Page A

## 概要

本ドキュメントは、webpackサンプルプロジェクト「many-pages」におけるPage Aの画面設計書である。Page Aはmany-pagesサンプルの7つのエントリポイントの1つであり、webpackのSplitChunksPluginによる自動チャンク分割の動作を示すデモページである。

### 本画面の処理概要

Page Aは、webpackの`optimization.splitChunks`機能を活用した共通チャンク最適化デモにおける1つのエントリポイントページである。複数のnpmモジュールとアプリケーションモジュールをインポートし、他のページとの共通モジュールが自動的に分割・共有される仕組みを示す。

**業務上の目的・背景**：webpackのSplitChunksPluginがどのように複数ページ間で共通モジュールを自動検出し、最適なチャンク分割を行うかを実証することが目的である。HTTP/2環境を想定した並列リクエスト最適化（maxInitialRequests: 20）と、最小チャンクサイズ（minSize: 40バイト）の設定による分割動作を確認できる。

**画面へのアクセス方法**：webpackビルド後に生成される`pageA.js`をHTMLファイルから読み込むことでアクセスする。エントリポイント名は`pageA`であり、webpack設定の`entry.pageA`として`./pages/a`が登録されている。

**主要な操作・処理内容**：
1. npmモジュール m1, m2, m3 をimport文で読み込む
2. アプリケーションモジュール stuff/s2, stuff/s3, stuff/s4 をimport文で読み込む
3. webpackのSplitChunksPluginにより、m1・m2はPage B, Page Cと共有チャンク（454.js）に分割される
4. m3はPage A固有のvendorチャンク（122.js）に分割される
5. stuff/s2, stuff/s3はPage D, Page Fと共有チャンク（554.js）に分割される
6. stuff/s4はPage Cとのみ共有だが、閾値未満のため分割されず重複保持される

**画面遷移**：many-pagesサンプルでは明示的な画面遷移は定義されていない。各ページは独立したエントリポイントとして動作し、共通モジュールによるチャンク共有関係のみが存在する。

**権限による表示制御**：該当なし。本サンプルには認証・認可機能は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | エントリポイント管理 | 主機能 | エントリポイントとして登録され、モジュールm1,m2,m3およびstuff/s2,s3,s4を読み込む |
| 12 | SplitChunksPlugin | 主機能 | 共通モジュール(m1,m2等)を他ページと共有するための自動チャンク分割 |
| 3 | モジュール処理 | 補助機能 | 各importモジュールの解析・変換処理 |
| 6 | 依存性解析 | 補助機能 | ESModule形式のimport依存関係を解析・追跡 |
| 10 | チャンクグラフ構築 | 補助機能 | 共有モジュールに基づくチャンクグラフの生成・管理 |
| 11 | チャンクグループ管理 | 補助機能 | 分割されたチャンクの並列読み込み制御 |
| 18 | 重複チャンク除去 | 補助機能 | 冗長な共有チャンクの検出・除去 |

## 画面種別

エントリポイントページ（webpackビルドデモ）

## URL/ルーティング

- エントリポイント名: `pageA`
- ソースパス: `./pages/a`（webpack.config.jsのentry設定）
- 出力ファイル: `pageA.js`（productionビルド時）

## 入出力項目

| 項目名 | 種別 | 型 | 説明 |
|--------|------|-----|------|
| m1 | 入力（import） | Module | npmモジュール。コンソールにメッセージを出力 |
| m2 | 入力（import） | Module | npmモジュール。コンソールにメッセージを出力 |
| m3 | 入力（import） | Module | npmモジュール。コンソールにメッセージを出力 |
| stuff/s2 | 入力（import） | Module | アプリケーションモジュール。コンソールにメッセージを出力 |
| stuff/s3 | 入力（import） | Module | アプリケーションモジュール。コンソールにメッセージを出力 |
| stuff/s4 | 入力（import） | Module | アプリケーションモジュール。コンソールにメッセージを出力 |

## 表示項目

本画面はUI表示を持たないwebpackビルドデモである。各モジュールのインポート時にコンソールへメッセージが出力される。

| 出力先 | 内容 | モジュール |
|--------|------|-----------|
| console | "a module installed from npm" | m1, m2, m3 |
| console | "some own module" | stuff/s2, stuff/s3, stuff/s4 |

## イベント仕様

### 1-ページ読み込み

ブラウザがエントリポイントファイル（pageA.js）および関連チャンクファイルを読み込む際、以下の処理が実行される。

1. webpackランタイムが初期化される
2. 共有vendorチャンク（454.js: m1, m2）が読み込まれる
3. Page A固有vendorチャンク（122.js: m3）が読み込まれる
4. 共有アプリケーションチャンク（554.js: s2, s3）が読み込まれる
5. pageA.jsエントリチャンクが実行され、各モジュールのimport文が解決される
6. 各モジュールの`console.log`が実行される

## データベース更新仕様

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

該当なし。本画面はデータベースを使用しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 出力条件 |
|-------------|------|---------------|---------|
| M-01 | 情報 | "a module installed from npm" | m1, m2, m3モジュール読み込み時にそれぞれ出力 |
| M-02 | 情報 | "some own module" | stuff/s2, s3, s4モジュール読み込み時にそれぞれ出力 |

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| チャンクファイルの読み込み失敗 | webpackランタイムがエラーをスローし、依存モジュールが解決されない |
| モジュール解決失敗 | webpack ModuleNotFoundError が発生（ビルド時に検出） |

## 備考

- minSizeが40バイトに設定されているため、実運用（デフォルト30KB）よりも細かくチャンクが分割される
- stuff/s4はPage AとPage Cの2ページのみで共有されるが、s4単体では閾値未満のため、各ページに重複して含まれる
- HTTP/2最適化のためmaxInitialRequests: 20に設定されており、多数の小チャンクが生成される

---

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

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

### 推奨読解順序

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

まず、各モジュールが何を提供するかを理解する。many-pagesサンプルでは全モジュールがconsole.logを実行するだけのシンプルな構造である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | m1.js | `examples/many-pages/node_modules/m1.js` | npmモジュールの実装。1行のconsole.log文のみ（行1） |
| 1-2 | m2.js | `examples/many-pages/node_modules/m2.js` | m1と同様の構造 |
| 1-3 | m3.js | `examples/many-pages/node_modules/m3.js` | m1と同様の構造 |
| 1-4 | s2.js | `examples/many-pages/stuff/s2.js` | アプリケーションモジュール。1行のconsole.log文のみ（行1） |
| 1-5 | s3.js | `examples/many-pages/stuff/s3.js` | s2と同様の構造 |
| 1-6 | s4.js | `examples/many-pages/stuff/s4.js` | s2と同様の構造 |

**読解のコツ**: node_modules配下のモジュール（m1〜m8）はnpmパッケージを模倣しており、stuff配下のモジュール（s1〜s8）はアプリケーション固有のモジュールを模倣している。SplitChunksPluginのcacheGroupはこの違いに基づいて`defaultVendors`と`default`に分類する。

#### Step 2: エントリーポイントを理解する

Page Aのエントリポイントファイルを読み、どのモジュールに依存しているかを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | a.js | `examples/many-pages/pages/a.js` | Page Aのエントリポイント。6つのimport文で依存モジュールを宣言（行1〜7） |

**主要処理フロー**:
1. **行1**: `import "m1"` - npmモジュールm1を読み込み（Page B, Cと共有）
2. **行2**: `import "m2"` - npmモジュールm2を読み込み（Page B, Cと共有）
3. **行3**: `import "m3"` - npmモジュールm3を読み込み（Page A固有）
4. **行5**: `import "../stuff/s2"` - アプリモジュールs2を読み込み（Page D, Fと共有）
5. **行6**: `import "../stuff/s3"` - アプリモジュールs3を読み込み（Page D, Fと共有）
6. **行7**: `import "../stuff/s4"` - アプリモジュールs4を読み込み（Page Cとのみ共有、閾値未満で重複）

#### Step 3: webpack設定を理解する

SplitChunksPluginの設定がどのようにチャンク分割に影響するかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | webpack.config.js | `examples/many-pages/webpack.config.js` | エントリポイント定義（行6〜14）とsplitChunks設定（行16〜22） |

**主要処理フロー**:
- **行6〜14**: entry設定で7ページ（pageA〜pageG）を定義
- **行17**: `chunks: "all"` で初期チャンクも含めた自動分割を有効化
- **行18**: `maxInitialRequests: 20` でHTTP/2向けの並列リクエスト上限を拡大
- **行19**: `maxAsyncRequests: 20` で非同期チャンクの並列リクエスト上限を拡大
- **行20**: `minSize: 40` でデモ用に閾値を40バイトに設定（デフォルト30KB）

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

```
webpack.config.js (エントリ定義)
    |
    +-- entry.pageA = "./pages/a"
            |
            +-- pages/a.js (エントリポイント)
                    |
                    +-- import "m1" --> node_modules/m1.js --> console.log(...)
                    +-- import "m2" --> node_modules/m2.js --> console.log(...)
                    +-- import "m3" --> node_modules/m3.js --> console.log(...)
                    +-- import "../stuff/s2" --> stuff/s2.js --> console.log(...)
                    +-- import "../stuff/s3" --> stuff/s3.js --> console.log(...)
                    +-- import "../stuff/s4" --> stuff/s4.js --> console.log(...)
```

### データフロー図

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

pages/a.js ────────────┐
                       |
node_modules/m1.js ───>|                                     pageA.js (エントリチャンク)
node_modules/m2.js ───>|   webpack SplitChunksPlugin         454.js (vendors: m1, m2 共有)
node_modules/m3.js ───>|   チャンク分割・最適化        ───>   122.js (vendors: m3 固有)
stuff/s2.js ──────────>|                                     554.js (default: s2, s3 共有)
stuff/s3.js ──────────>|                                     ※s4はpageA.jsに含有
stuff/s4.js ──────────>|
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| a.js | `examples/many-pages/pages/a.js` | ソース | Page Aのエントリポイント |
| webpack.config.js | `examples/many-pages/webpack.config.js` | 設定 | webpackビルド設定・SplitChunks設定 |
| m1.js | `examples/many-pages/node_modules/m1.js` | ソース | npmモジュール（vendor）。Page B, Cと共有 |
| m2.js | `examples/many-pages/node_modules/m2.js` | ソース | npmモジュール（vendor）。Page B, Cと共有 |
| m3.js | `examples/many-pages/node_modules/m3.js` | ソース | npmモジュール（vendor）。Page A固有 |
| s2.js | `examples/many-pages/stuff/s2.js` | ソース | アプリモジュール。Page D, Fと共有 |
| s3.js | `examples/many-pages/stuff/s3.js` | ソース | アプリモジュール。Page D, Fと共有 |
| s4.js | `examples/many-pages/stuff/s4.js` | ソース | アプリモジュール。Page Cとのみ共有（重複） |
| README.md | `examples/many-pages/README.md` | ドキュメント | サンプルの解説・ビルド結果の説明 |
| build.js | `examples/many-pages/build.js` | ソース | ビルドスクリプト |
