# 画面設計書 10-Login

## 概要

本ドキュメントは、webpackサンプルプロジェクト「reexport-components」におけるLoginページの画面設計書である。Loginは、Reactベースのログインページであり、ButtonコンポーネントとDialogコンポーネントを使用する。webpackのTree Shaking機能による未使用エクスポートの除去を実証するサンプルである。

### 本画面の処理概要

Loginページは、Reactコンポーネントとして実装されたログイン画面である。`components/index.js`からの再エクスポート（re-export）パターンを介してButtonとDialogをインポートし、JSXで描画する。webpackのTree Shaking（usedExports + sideEffects）およびInnerGraph解析により、LoginページではButtonとDialogのみがバンドルに含まれ、未使用のCheckboxやDialogInlineは除去される。

**業務上の目的・背景**：webpackのTree Shaking機能がre-exportパターン（barrel export）において正しく動作することを実証する。`components/index.js`が全コンポーネントを再エクスポートする設計でも、Loginページが実際に使用するButtonとDialogのみがバンドルに含まれることを確認できる。InnerGraph解析（webpack 5の機能）により、re-export経由でも精密な使用追跡が可能である。

**画面へのアクセス方法**：example.jsから`import(\`./pages/${page}\`)`で動的にインポートされる。`page`変数が"Login"の場合にLogin.jsが読み込まれる。

**主要な操作・処理内容**：
1. example.jsがimport()でLogin.jsを動的に読み込む
2. Login.jsが`components/index.js`からButtonとDialogを名前付きインポートする
3. webpackのTree Shakingにより、未使用のCheckboxとDialogInlineはバンドルから除去される
4. Loginコンポーネントが`<Button />`と`<Dialog />`を描画するJSXを返す
5. babel-loaderの@babel/reactプリセットによりJSXがJavaScriptに変換される

**画面遷移**：
- example.jsからの動的import()でアクセスされる
- Dashboardページとの切り替えが可能（example.jsのpage変数による）
- LoginページからDashboardへの明示的な遷移UIは実装されていない

**権限による表示制御**：該当なし。本サンプルには認証・認可機能は実装されていない。ログインページはUIデモであり、実際の認証処理は含まない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | Tree Shaking | 主機能 | Button,Dialogのみインポートし、未使用のCheckbox等を除去する最適化 |
| 13 | 動的インポート | 主機能 | example.jsからimport(./pages/Login)で動的に読み込まれる |
| 8 | JavaScriptパーサ | 補助機能 | JSX構文を含むReactコンポーネントの解析 |
| 16 | InnerGraph解析 | 補助機能 | re-exportパターンにおける変数使用追跡で精密なTree Shakingを実現 |
| 14 | モジュール連結（Scope Hoisting） | 補助機能 | コンポーネントモジュール群のスコープ結合による最適化 |
| 3 | モジュール処理 | 補助機能 | Reactコンポーネントモジュールの解析・変換 |

## 画面種別

Reactページコンポーネント（ログイン画面デモ）

## URL/ルーティング

- 動的インポートパス: `./pages/Login`（example.jsからのimport()）
- ソースファイル: `examples/reexport-components/pages/Login.js`

## 入出力項目

| 項目名 | 種別 | 型 | 説明 |
|--------|------|-----|------|
| Button | 入力（import） | React.Component | ボタンコンポーネント。`<button />`要素を描画 |
| Dialog | 入力（import） | React.Component | ダイアログコンポーネント。`<dialog>`要素を描画。children propを受け取る |
| Login | 出力（export default） | React.Component | ログインページコンポーネント。ButtonとDialogを描画 |

## 表示項目

| 要素 | HTMLタグ | コンポーネント | 説明 |
|------|---------|---------------|------|
| ボタン | `<button />` | Button | ログインボタン（属性なし） |
| ダイアログ | `<dialog></dialog>` | Dialog | ダイアログ要素（childrenなし） |

## イベント仕様

### 1-ページ読み込み（動的import）

example.jsからLoginページが動的にインポートされる際の処理フロー。

1. example.jsが`import(\`./pages/${page}\`)`を実行（pageが"Login"の場合）
2. webpackランタイムがLogin.jsを含むチャンクを動的にフェッチ
3. Login.jsが評価され、ButtonとDialogがcomponents/index.jsを経由してインポートされる
4. Tree Shakingにより、CheckboxとDialogInlineはバンドルに含まれない
5. Loginコンポーネントがdefault exportとして公開される

### 2-コンポーネント描画

Loginコンポーネントが描画される際の処理。

1. Loginコンポーネントの関数が呼び出される
2. React Fragment (`<>...</>`) 内にButtonとDialogが描画される
3. Buttonは`<button />`として描画される
4. Dialogは`<dialog></dialog>`として描画される（childrenなし）

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

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

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

## メッセージ仕様

該当なし。本画面にはメッセージ出力の仕組みは実装されていない。

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| 動的importの失敗 | import()のPromiseがrejectされる |
| JSXのレンダリングエラー | Reactのエラーバウンダリがない場合、アプリケーションがクラッシュする |

## 備考

- Login.jsはJSX構文を使用するため、babel-loader + @babel/reactプリセットによるトランスパイルが必要
- components/index.jsはbarrel export（再エクスポート）パターンを採用しており、4つのコンポーネント（Button, Checkbox, Dialog, DialogInline）を公開する
- LoginページはButtonとDialogのみを使用するため、Tree ShakingによりCheckboxとDialogInlineが除去される
- webpack設定でsideEffects: trueおよびusedExports: trueが有効化されている
- chunkIdsとmoduleIdsがともに"named"に設定されており、開発時の可読性を確保
- DialogInlineは名前付きエクスポート、Dialogはデフォルトエクスポートの再エクスポートであり、異なるエクスポートパターンのTree Shakingを示す

---

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

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

### 推奨読解順序

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

まず、コンポーネントの構成とre-exportパターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.js | `examples/reexport-components/components/index.js` | barrel export。4コンポーネントを再エクスポート（行1〜4）。エクスポート形式の違いに注目 |
| 1-2 | Button.js | `examples/reexport-components/components/Button.js` | Buttonコンポーネント。`<button />`を描画。export { Button as default }形式（行1〜4） |
| 1-3 | Dialog.js | `examples/reexport-components/components/Dialog.js` | Dialogコンポーネント。children propを受け取る`<dialog>`要素。export default形式（行1〜4） |
| 1-4 | Checkbox.js | `examples/reexport-components/components/Checkbox.js` | Checkboxコンポーネント（Loginでは未使用、Tree Shakingで除去）（行1〜4） |
| 1-5 | DialogInline.js | `examples/reexport-components/components/DialogInline.js` | DialogInlineコンポーネント（Loginでは未使用、Tree Shakingで除去）（行1〜4） |

**読解のコツ**: components/index.jsの再エクスポート形式に注目する。`export { default as Button }` はデフォルトエクスポートの再エクスポート、`export * from "./Checkbox"` は名前付きエクスポートの一括再エクスポートである。webpackのInnerGraph解析はこれらのパターンを追跡して、実際に使用されるエクスポートのみを残す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | example.js | `examples/reexport-components/example.js` | アプリケーションエントリ。動的import()でページを読み込み（行2） |
| 2-2 | Login.js | `examples/reexport-components/pages/Login.js` | Loginページコンポーネント。ButtonとDialogをimportし、JSXで描画（行1〜11） |

**主要処理フロー（Login.js）**:
1. **行1**: `import { Button, Dialog } from "../components"` - components/index.jsからButton, Dialogを名前付きインポート
2. **行3〜10**: `const Login = () => { ... }` - Loginコンポーネントを関数宣言
3. **行5〜8**: JSXで`<Button />`と`<Dialog />`をReact Fragmentで囲んで描画
4. **行11**: `export default Login` - デフォルトエクスポート

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | webpack.config.js | `examples/reexport-components/webpack.config.js` | babel-loader設定（行8〜18）、Tree Shaking最適化設定（行21〜27） |

**主要処理フロー（webpack.config.js）**:
- **行9**: `.js`ファイルにbabel-loaderを適用
- **行14**: `@babel/react`プリセットでJSXをトランスパイル
- **行25**: `sideEffects: true` - package.jsonのsideEffectsフィールドを尊重
- **行26**: `usedExports: true` - 未使用エクスポートの検出を有効化

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

```
example.js (エントリポイント)
    |
    +-- import(`./pages/${page}`)  [page = "Login"]
            |
            +-- pages/Login.js (Loginページコンポーネント)
                    |
                    +-- import { Button, Dialog } from "../components"
                            |
                            +-- components/index.js (barrel export)
                                    |
                                    +-- Button.js --> <button /> [使用される]
                                    +-- Dialog.js --> <dialog> [使用される]
                                    +-- Checkbox.js [Tree Shakingで除去]
                                    +-- DialogInline.js [Tree Shakingで除去]
```

### データフロー図

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

example.js ──────────> import("./pages/Login")
                              |
                              v
Login.js ────────────> import { Button, Dialog }
                              |
                              v
components/index.js    Tree Shaking + InnerGraph      Login コンポーネント
    |                  解析により未使用エクスポート     (<> <Button /> <Dialog /> </>)
    +-- Button.js ───> 使用される ──────────────────> バンドルに含有
    +-- Dialog.js ───> 使用される ──────────────────> バンドルに含有
    +-- Checkbox.js -> 未使用 ─────────────────────> バンドルから除去
    +-- DialogInline -> 未使用 ────────────────────> バンドルから除去
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Login.js | `examples/reexport-components/pages/Login.js` | ソース | Loginページコンポーネント |
| example.js | `examples/reexport-components/example.js` | ソース | アプリケーションエントリポイント。動的importでページを読み込み |
| index.js | `examples/reexport-components/components/index.js` | ソース | barrel export。全コンポーネントを再エクスポート |
| Button.js | `examples/reexport-components/components/Button.js` | ソース | Buttonコンポーネント（Loginで使用） |
| Dialog.js | `examples/reexport-components/components/Dialog.js` | ソース | Dialogコンポーネント（Loginで使用） |
| Checkbox.js | `examples/reexport-components/components/Checkbox.js` | ソース | Checkboxコンポーネント（Loginでは未使用） |
| DialogInline.js | `examples/reexport-components/components/DialogInline.js` | ソース | DialogInlineコンポーネント（Loginでは未使用） |
| Dashboard.js | `examples/reexport-components/pages/Dashboard.js` | ソース | Dashboardページ（別ページ。Buttonを共有） |
| webpack.config.js | `examples/reexport-components/webpack.config.js` | 設定 | babel-loader設定、Tree Shaking最適化設定 |
