# 画面設計書 24-App

## 概要

本ドキュメントは、webpack DLL パターンサンプルにおけるメインアプリケーション（App）の画面設計書である。DLL（Dynamic Link Library）パターンを活用し、事前にコンパイル済みの vendor バンドルを参照することで、アプリケーションのビルド速度を向上させるデモンストレーションである。

### 本画面の処理概要

本アプリケーションは、webpack の DllPlugin / DllReferencePlugin を使用した DLL パターンのメイン部分（App）であり、事前にビルドされた vendor バンドルから提供されるモジュール（example-vendor）を利用してコンソールに計算結果を出力する。

**業務上の目的・背景**：大規模なアプリケーション開発において、変更頻度の低い vendor ライブラリを事前にコンパイルして DLL バンドルとして分離することで、日常的なアプリケーションビルドの速度を大幅に向上させることが目的である。vendor バンドルのビルドは一度だけ行い、そのマニフェストファイル（vendor-manifest.json）を通じてアプリケーションビルドから参照する。これにより、vendor のコードはアプリケーションビルド時に再コンパイルされないため、ビルド時間が短縮される。

**画面へのアクセス方法**：`example.html` を開くことでアプリケーションにアクセスする。HTML ファイル内で、まず vendor バンドル（`../0-vendor/js/vendor.js`）が読み込まれ、その後にアプリケーションバンドル（`js/app.js`）が読み込まれる。スクリプトの読み込み順序が重要であり、vendor が先に読み込まれる必要がある。

**主要な操作・処理内容**：
1. `example-vendor` モジュールから `square` 関数を名前付きインポートする
2. `square(7)` を関数として呼び出し、結果（49）をコンソールに出力する
3. `new square(7)` をコンストラクタとして呼び出し、結果をコンソールに出力する

**画面遷移**：本アプリケーションは単一のエントリポイントであり、画面遷移は存在しない。

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 67 | DllPlugin / DllReferencePlugin | 主機能 | DllReferencePluginにより事前コンパイル済みvendorバンドルのマニフェストを参照 |
| 4 | エントリポイント管理 | 補助機能 | メインアプリケーションのエントリポイント登録 |
| 3 | モジュール処理 | 補助機能 | DLLモジュール(example-vendor)の参照・解決処理 |

## 画面種別

単一ページアプリケーション（コンソール出力）

## URL/ルーティング

`example.html` が静的 HTML ファイルとして提供される。特定のルーティング設定は存在しない。

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| (なし) | - | - | - | ユーザーからの入力はなし |

## 表示項目

| 表示項目 | データソース | 表示形式 | 説明 |
|----------|-------------|----------|------|
| square(7) の結果 | example-vendor の square 関数 | console.log出力 | `square(7)` の計算結果（49）をコンソールに出力 |
| new square(7) の結果 | example-vendor の square 関数 | console.log出力 | `new square(7)` のコンストラクタ呼び出し結果をコンソールに出力 |

## イベント仕様

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

`example.html` がブラウザで開かれた際の処理フロー。

1. `../0-vendor/js/vendor.js`（DLLバンドル）が読み込まれ、グローバル変数 `vendor_lib_[fullhash]` として vendor ライブラリが公開される
2. `js/app.js`（アプリケーションバンドル）が読み込まれる
3. DllReferencePlugin により、`example-vendor` モジュールのインポートが DLL バンドル内のモジュールに解決される
4. `square(7)` が関数として呼び出され、`7 * 7 = 49` がコンソールに出力される
5. `new square(7)` がコンストラクタとして呼び出され、結果がコンソールに出力される

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

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

本画面にデータベース操作は存在しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| - | コンソール出力 | `49` | ページ読み込み時（square(7) の結果） |
| - | コンソール出力 | `square {}` (オブジェクト) | ページ読み込み時（new square(7) の結果） |

## 例外処理

| 例外 | 発生条件 | 対応 |
|------|----------|------|
| vendor バンドル未読み込みエラー | vendor.js が app.js より先に読み込まれなかった場合 | `example-vendor` モジュールの解決に失敗し、ランタイムエラーが発生する |
| マニフェスト不一致エラー | vendor-manifest.json が存在しないか、vendor バンドルのビルドと整合しない場合 | webpack ビルド時にエラーが発生する |
| vendor バンドルの再ビルド必要 | vendor のソースコードが変更されたが DLL バンドルが再ビルドされていない場合 | 古いバージョンの vendor コードが使用される |

## 備考

- DLL パターンは2段階のビルドプロセスを必要とする。まず `0-vendor` ディレクトリで vendor バンドルをビルドし（DllPlugin でマニフェストを生成）、その後 `1-app` ディレクトリでアプリケーションをビルドする（DllReferencePlugin でマニフェストを参照）
- vendor バンドルの output.library は `"vendor_lib_[fullhash]"` に設定されており、ハッシュ値によってバージョン管理される
- `new square(7)` の使用は、`square` 関数をコンストラクタとして呼び出すデモンストレーションであるが、`square` 関数は単に `n * n` を返すだけであるため、コンストラクタとしての使用は `square {}` オブジェクトを返す
- DllPlugin は webpack 5 でもサポートされているが、一般的には SplitChunksPlugin やモジュールフェデレーションが推奨されている

---

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

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

### 推奨読解順序

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

DLL バンドルが提供するモジュールの内容を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | example-vendor.js | `examples/dll-app-and-vendor/node_modules/example-vendor.js` | vendor パッケージの実装。`square` 関数が `n * n` を返す |

**読解のコツ**: `node_modules/example-vendor.js` はローカルに配置された疑似 npm パッケージである。ES Modules の named export パターン（`export function square(n)`）で関数を公開している。

#### Step 2: エントリーポイントを理解する（アプリケーション側）

メインアプリケーションの処理内容を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | example-app.js | `examples/dll-app-and-vendor/1-app/example-app.js` | アプリケーションのエントリポイント。example-vendor から square をインポートし、関数呼び出しとコンストラクタ呼び出しを行う |

**主要処理フロー**:
1. **1行目**: `import { square } from "example-vendor"` で vendor モジュールから square 関数をインポート
2. **3行目**: `console.log(square(7))` で square(7) の結果をコンソール出力
3. **4行目**: `console.log(new square(7))` で square をコンストラクタとして呼び出し結果をコンソール出力

#### Step 3: ビルド設定を理解する（アプリケーション側）

DllReferencePlugin の設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | webpack.config.js (1-app) | `examples/dll-app-and-vendor/1-app/webpack.config.js` | DllReferencePlugin の設定。vendor-manifest.json を参照してモジュール解決を行う |

**主要処理フロー**:
- **6行目**: `const manifest = "../0-vendor/dist/vendor-manifest.json"` でマニフェストパスを定義
- **12行目**: `entry: "./example-app"` でエントリポイントを設定
- **18-20行目**: `new webpack.DllReferencePlugin({ manifest: require(manifest) })` でDLLマニフェストを参照

#### Step 4: ビルド設定を理解する（vendor 側）

DllPlugin による vendor バンドルの生成方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | webpack.config.js (0-vendor) | `examples/dll-app-and-vendor/0-vendor/webpack.config.js` | DllPlugin の設定。vendor バンドルとマニフェストファイルを生成する |

**主要処理フロー**:
- **10行目**: `entry: ["example-vendor"]` で vendor エントリを設定
- **12行目**: `filename: "vendor.js"` で出力ファイル名を設定
- **14行目**: `library: "vendor_lib_[fullhash]"` でグローバル変数名を設定
- **17-19行目**: `new webpack.DllPlugin({ name: "vendor_lib_[fullhash]", path: ... })` でマニフェスト生成

#### Step 5: HTML によるスクリプト読み込み順序を理解する

ブラウザでの実行時のスクリプト読み込み順序を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | example.html | `examples/dll-app-and-vendor/1-app/example.html` | vendor.js を先に、app.js を後に読み込む順序を確認 |

**主要処理フロー**:
- **4行目**: `<script src="../0-vendor/js/vendor.js">` で vendor DLL バンドルを先に読み込み
- **5行目**: `<script src="js/app.js">` でアプリケーションバンドルを後に読み込み

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

```
example.html
    │
    ├─ vendor.js (DLLバンドル: 0-vendor)
    │      └─ DllPlugin
    │             └─ example-vendor.js
    │                    └─ export function square(n) { return n * n; }
    │
    └─ app.js (アプリケーションバンドル: 1-app)
           └─ DllReferencePlugin
                  └─ vendor-manifest.json 参照
                         └─ example-app.js
                                ├─ import { square } from "example-vendor"
                                │      └─ DLL内のsquareモジュールに解決
                                ├─ console.log(square(7))    → 49
                                └─ console.log(new square(7)) → square {}
```

### データフロー図

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

0-vendor/webpack.config.js
  │
  └─ example-vendor.js   ───▶ DllPlugin                    ───▶ vendor.js (DLLバンドル)
                               (vendor ビルド)                     vendor-manifest.json
                                                                       │
1-app/webpack.config.js                                               │
  │                                                                    │
  └─ example-app.js      ───▶ DllReferencePlugin           ───▶ app.js
       │                       (manifest参照でモジュール解決)          │
       │                                                              │
       └─ square(7)       ───▶ DLL内のsquare関数            ───▶ console.log(49)
       └─ new square(7)   ───▶ DLL内のsquare関数            ───▶ console.log(square {})
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| example-app.js | `examples/dll-app-and-vendor/1-app/example-app.js` | ソース | メインアプリケーションのエントリポイント |
| webpack.config.js (1-app) | `examples/dll-app-and-vendor/1-app/webpack.config.js` | 設定 | アプリケーション側のwebpack設定。DllReferencePlugin使用 |
| example.html | `examples/dll-app-and-vendor/1-app/example.html` | テンプレート | HTMLファイル。vendor.jsとapp.jsの読み込み順序を定義 |
| example-vendor.js | `examples/dll-app-and-vendor/node_modules/example-vendor.js` | ソース | vendorパッケージ。square関数を提供 |
| webpack.config.js (0-vendor) | `examples/dll-app-and-vendor/0-vendor/webpack.config.js` | 設定 | vendor側のwebpack設定。DllPlugin使用 |
| README.md | `examples/dll-app-and-vendor/README.md` | ドキュメント | DLLパターンの概要説明 |
