# 画面設計書 13-Page B

## 概要

本ドキュメントは、webpackサンプルプロジェクト「multiple-entry-points」に含まれるPage B画面の設計仕様を記載する。Page Aと同様に複数エントリポイント構成における共通モジュール共有チャンク化を実証するページであるが、非同期読み込みにrequire.ensure形式を使用する点で異なる。

### 本画面の処理概要

Page Bは、multiple-entry-pointsサンプルにおいてPage Aと共通モジュール（common.js）を共有し、SplitChunksPluginによるcommonsチャンクの自動生成を検証する画面である。

**業務上の目的・背景**：本画面はwebpackの複数エントリポイント構成における共通モジュール抽出のもう一方のページとして存在する。Page Aと同一のcommon.jsに依存することで、SplitChunksPluginの`minChunks: 2`条件を満たし、commons.jsチャンクが生成されることを検証する。さらに、`require.ensure`形式の非同期読み込みパターンを実証する役割も持つ。

**画面へのアクセス方法**：Page B単独のHTMLファイルは提供されていない。pageAB.htmlにてPage Aと共にスクリプトが読み込まれる構成となっている。HTMLファイルでは`commons.js` → `pageA.bundle.js` → `pageB.bundle.js`の順にロードされる。

**主要な操作・処理内容**：
1. pageB.jsがエントリポイントとして実行され、common.jsモジュールをrequireで同期読み込みする
2. `require.ensure(["./shared"], callback)`によりsharedモジュールの非同期読み込みを保証する
3. コールバック内で`require("./shared")`を再度呼び出してsharedモジュールを取得し、`shared("This is page B")`を実行してコンソールに出力する

**画面遷移**：pageAB.htmlでPage Aと同時に読み込まれる。単独のHTMLページは提供されていない。明示的な画面間遷移は定義されていない。

**権限による表示制御**：権限による表示制御は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | エントリポイント管理 | 主機能 | 複数エントリポイントの一つとして登録。common.jsを共有 |
| 12 | SplitChunksPlugin | 主機能 | commons.jsチャンクとしてcommon.jsをPageAと共有分割 |
| 6 | 依存性解析 | 補助機能 | CommonJS(require)形式の依存関係を解析 |
| 13 | 動的インポート | 補助機能 | require.ensureによる./sharedモジュールの非同期読み込み |
| 3 | モジュール処理 | 補助機能 | 共通モジュールおよびページ固有モジュールの解析・変換 |

## 画面種別

エントリポイントページ（コンソール出力のみ）

## URL/ルーティング

- `pageAB.html` - Page AとPage Bの複合表示

HTMLファイルでのスクリプト読み込み順序：
1. `js/commons.js` （共通チャンク）
2. `js/pageA.bundle.js` （Page A固有チャンク）
3. `js/pageB.bundle.js` （Page B固有チャンク）

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| なし | - | - | - | 本画面はユーザー入力を受け付けない |

## 表示項目

| 項目名 | 種別 | 出力先 | 説明 |
|--------|------|--------|------|
| "This is page B" | コンソール出力 | console.log | sharedモジュール経由で出力されるメッセージ |

## イベント仕様

### 1-ページ読み込み（同期処理）

pageB.jsの実行開始時、行1で`var common = require("./common")`が同期的に実行される。common.jsは文字列`"Common"`をexportするモジュールであり、変数`common`に格納される。

### 2-非同期モジュール読み込み（require.ensure形式）

行2-5の`require.ensure(["./shared"], callback)`により、sharedモジュールのチャンクが事前にロードされることが保証される。チャンクロード完了後、コールバック関数が実行され、内部の`require("./shared")`でsharedモジュールを取得。`shared("This is page B")`を呼び出してconsole.logで出力する。

AMD形式（Page A）との違い：
- `require.ensure`はチャンクの事前ロードを保証する仕組みであり、コールバック内で明示的に`require`を呼ぶ必要がある
- AMD形式`require([], callback)`はコールバック引数として直接モジュールが渡される

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | - | - | 本画面はフロントエンドのみのデモであり、データベース操作は存在しない |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| M-01 | 情報（コンソール） | "This is page B" | sharedモジュールの非同期読み込み完了後 |

## 例外処理

| 例外 | 条件 | 動作 |
|------|------|------|
| commons.jsロード失敗 | 共通チャンクファイルが見つからない場合 | pageB.bundle.jsの実行がcommon.jsの未定義エラーで失敗する |
| require.ensureチャンクロード失敗 | sharedモジュールのチャンクが読み込めない場合 | ensure時にエラーハンドラが呼ばれる（未定義の場合はサイレント失敗） |

## 備考

- Page Aと異なり、`require.ensure`形式（webpack 1/2時代のコード分割API）を使用している
- `require.ensure`はwebpack 4以降でもサポートされるが、現在は`import()`が推奨される
- Page B単独のHTMLテンプレートは提供されておらず、pageAB.htmlでPage Aと共に読み込まれる
- commons.jsチャンクにはcommon.jsが含まれ、pageAとpageBで共有される

---

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

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

### 推奨読解順序

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

共通モジュールとsharedモジュールのデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | common.js | `examples/multiple-entry-points/common.js` | `module.exports = "Common"` で文字列を公開。pageAとpageBの両方で共有される |
| 1-2 | shared.js | `examples/multiple-entry-points/shared.js` | common.jsをrequireし、引数のメッセージをconsole.logで出力する関数をexportする |

**読解のコツ**: `require.ensure`はwebpackの旧式コード分割APIであり、第1引数の配列がチャンクの依存宣言、第2引数のコールバック内で実際のrequireを行うパターンに注目する。

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

Page Bのエントリーポイントファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pageB.js | `examples/multiple-entry-points/pageB.js` | 行1: CommonJS形式でcommon.jsを同期require。行2-5: require.ensure形式でshared.jsの非同期保証付き読み込みを実行 |

**主要処理フロー**:
1. **行1**: `var common = require("./common")` - common.jsを同期的に読み込み
2. **行2**: `require.ensure(["./shared"], function(require) {` - sharedのチャンクロードを保証
3. **行3**: `var shared = require("./shared")` - ロード済みのsharedモジュールを同期取得
4. **行4**: `shared("This is page B")` - shared関数を呼び出してメッセージ出力

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

SplitChunksPluginの設定を確認する。Page Aと同一の設定ファイルである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | webpack.config.js | `examples/multiple-entry-points/webpack.config.js` | 行6-9: pageBがエントリポイントとして登録。行11-19: commonsキャッシュグループの設定 |

#### Step 4: HTMLテンプレートを理解する

Page BはpageAB.htmlでのみ使用される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | pageAB.html | `examples/multiple-entry-points/pageAB.html` | commons.js → pageA.bundle.js → pageB.bundle.jsの順にロード。Page B単独のHTMLは存在しない |

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

```
pageB.js [エントリポイント]
    |
    +-- require("./common")  [同期読み込み]
    |       |
    |       +-- common.js  -> "Common"
    |
    +-- require.ensure(["./shared"], callback)  [チャンクロード保証]
            |
            +-- require("./shared")  [コールバック内で同期取得]
                    |
                    +-- shared.js
                            |
                            +-- require("./common")  -> "Common"
                            +-- console.log("This is page B")
```

### データフロー図

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

HTMLロード              commons.jsチャンク読み込み
(pageAB.html) -----> (common.js含む)
                           |
                      pageB.bundle.js実行
                           |
                      +----+-----+
                      |          |
                common.js   require.ensure
                (同期)       sharedチャンク保証
                                |
                           require("./shared")        console.log
                           (同期取得)         ------> "This is page B"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pageB.js | `examples/multiple-entry-points/pageB.js` | ソース | Page Bのエントリポイント |
| pageA.js | `examples/multiple-entry-points/pageA.js` | ソース | Page Aのエントリポイント（共通チャンク共有先） |
| common.js | `examples/multiple-entry-points/common.js` | ソース | 共通モジュール。pageAとpageBで共有 |
| shared.js | `examples/multiple-entry-points/shared.js` | ソース | 非同期読み込みモジュール。メッセージ出力関数 |
| webpack.config.js | `examples/multiple-entry-points/webpack.config.js` | 設定 | エントリポイントとSplitChunksPluginの設定 |
| pageAB.html | `examples/multiple-entry-points/pageAB.html` | テンプレート | Page A+B複合表示用HTML |
