488 lines
14 KiB
Markdown
488 lines
14 KiB
Markdown
# DramaLing 前端系統架構分析報告
|
||
|
||
## 📋 專案概覽
|
||
|
||
**技術棧**:
|
||
- **框架**:Next.js 15.5.3 (App Router)
|
||
- **語言**:TypeScript 5.9.2
|
||
- **狀態管理**:Zustand 5.0.8
|
||
- **樣式**:Tailwind CSS 3.4.17
|
||
- **圖標**:Lucide React
|
||
- **部署**:Zeabur
|
||
|
||
**專案規模**:
|
||
- 約 150+ 個組件和模組文件
|
||
- 8 個主要路由頁面
|
||
- 5 個 Zustand Store
|
||
- 多層級的服務和工具函數架構
|
||
|
||
## 🏗️ 系統架構層次
|
||
|
||
### 1. 目錄結構分析
|
||
|
||
```
|
||
frontend/
|
||
├── app/ # Next.js App Router 頁面
|
||
│ ├── flashcards/ # 詞卡管理頁面
|
||
│ ├── generate/ # AI 生成頁面
|
||
│ ├── review/ # 複習系統頁面
|
||
│ ├── review-design/ # 複習設計頁面
|
||
│ └── settings/ # 設定頁面
|
||
├── components/ # React 組件庫
|
||
│ ├── shared/ # 共享基礎組件 (12個)
|
||
│ ├── flashcards/ # 詞卡功能組件 (10個)
|
||
│ ├── review/ # 複習系統組件 (20+個)
|
||
│ ├── generate/ # AI生成組件 (5個)
|
||
│ ├── ui/ # 基礎UI組件 (1個)
|
||
│ ├── word/ # 詞彙分析組件 (3個)
|
||
│ └── media/ # 媒體組件 (已重構)
|
||
├── hooks/ # 自定義 Hook 層
|
||
│ ├── flashcards/ # 詞卡邏輯 (7個)
|
||
│ ├── review/ # 複習邏輯 (2個)
|
||
│ ├── generate/ # 生成邏輯 (2個)
|
||
│ └── shared/ # 共享邏輯 (1個)
|
||
├── store/ # Zustand 狀態管理
|
||
│ ├── useReviewSessionStore.ts # 複習會話
|
||
│ ├── useTestQueueStore.ts # 測試佇列
|
||
│ ├── useReviewDataStore.ts # 複習數據
|
||
│ ├── useTestResultStore.ts # 測試結果
|
||
│ └── useUIStore.ts # UI狀態
|
||
├── lib/ # 核心服務層
|
||
│ ├── services/ # API 服務
|
||
│ ├── utils/ # 工具函數
|
||
│ ├── types/ # 類型定義
|
||
│ └── config/ # 配置管理
|
||
└── types/ # 全域類型定義
|
||
```
|
||
|
||
## 🎯 架構設計模式分析
|
||
|
||
### 2.1 分層架構模式 (Layered Architecture)
|
||
|
||
```
|
||
┌─────────────────┐
|
||
│ 表現層 (UI) │ ← React 組件
|
||
├─────────────────┤
|
||
│ 業務邏輯層 │ ← Custom Hooks
|
||
├─────────────────┤
|
||
│ 狀態管理層 │ ← Zustand Stores
|
||
├─────────────────┤
|
||
│ 服務層 (API) │ ← API Services
|
||
└─────────────────┘
|
||
```
|
||
|
||
**設計優勢**:
|
||
- ✅ 職責分離清晰
|
||
- ✅ 層次間耦合度低
|
||
- ✅ 易於測試和維護
|
||
- ✅ 支援並行開發
|
||
|
||
### 2.2 Hooks + Store 雙層模式
|
||
|
||
**Hook 層**(業務邏輯封裝):
|
||
- 包裝 Store 操作 + API 呼叫
|
||
- 提供組件友好的介面
|
||
- 處理複雜的業務邏輯
|
||
|
||
**Store 層**(純狀態管理):
|
||
- Zustand 全域狀態
|
||
- 跨組件狀態同步
|
||
- 最小重渲染優化
|
||
|
||
## 📊 組件架構分析
|
||
|
||
### 3.1 共享組件庫 (components/shared/)
|
||
|
||
**基礎組件** (12個):
|
||
- `BluePlayButton` - 統一播放按鈕 🆕
|
||
- `ContentBlock` - 內容區塊
|
||
- `ErrorState` - 錯誤狀態顯示
|
||
- `LoadingState` - 載入狀態
|
||
- `Modal` - 彈窗組件
|
||
- `Navigation` - 導航列
|
||
- `PaginationControls` - 分頁控制
|
||
- `ProtectedRoute` - 路由保護
|
||
- `StatisticsCard` - 統計卡片
|
||
- `TabNavigation` - 標籤導航
|
||
- `Toast` - 通知系統
|
||
- `ValidatedTextInput` - 驗證輸入框
|
||
|
||
**設計評價**:⭐⭐⭐⭐⭐
|
||
- 組件職責單一,重用性高
|
||
- API 設計一致,易於使用
|
||
- 支援主題化和客製化
|
||
|
||
### 3.2 功能專用組件
|
||
|
||
**詞卡組件** (10個):
|
||
- 完整的 CRUD 操作組件
|
||
- 圖片生成和管理組件
|
||
- 搜尋和篩選組件
|
||
|
||
**複習組件** (20+個):
|
||
- 7 種複習模式的測試組件
|
||
- 統一的測試結果顯示
|
||
- 進度追蹤組件
|
||
|
||
**AI生成組件** (5個):
|
||
- 句子分析組件
|
||
- 詞彙選擇組件
|
||
- 慣用語展示組件
|
||
|
||
## 🔄 狀態管理分析
|
||
|
||
### 4.1 Zustand Store 設計
|
||
|
||
**架構優勢**:
|
||
- 使用 `subscribeWithSelector` 中間件優化性能
|
||
- Store 按功能域分離,避免巨大單體
|
||
- 狀態更新邏輯集中化
|
||
|
||
**Store 職責劃分**:
|
||
|
||
1. **useReviewSessionStore** - 複習會話核心狀態
|
||
- 當前詞卡、進度、模式設定
|
||
- 會話生命週期管理
|
||
|
||
2. **useTestQueueStore** - 測試佇列邏輯
|
||
- 智能優先級算法
|
||
- 測試順序管理
|
||
|
||
3. **useReviewDataStore** - 複習資料管理
|
||
- 待複習詞卡載入
|
||
- 數據快取機制
|
||
|
||
4. **useTestResultStore** - 測試結果追蹤
|
||
- 答題結果記錄
|
||
- 統計數據計算
|
||
|
||
5. **useUIStore** - UI 狀態管理
|
||
- 全域 UI 狀態
|
||
- 主題和設定
|
||
|
||
### 4.2 Hook 封裝層
|
||
|
||
**設計模式**:Store 包裝器 + 業務邏輯
|
||
|
||
```typescript
|
||
// 範例:useReviewSession Hook
|
||
export const useReviewSession = () => {
|
||
const store = useReviewSessionStore()
|
||
|
||
// 業務邏輯:載入下一張卡片
|
||
const loadNextCard = async () => {
|
||
try {
|
||
store.setLoading(true)
|
||
const result = await flashcardsService.getDueFlashcards()
|
||
store.setDueCards(result.data)
|
||
} catch (error) {
|
||
store.setError(error.message)
|
||
} finally {
|
||
store.setLoading(false)
|
||
}
|
||
}
|
||
|
||
return { ...store, loadNextCard }
|
||
}
|
||
```
|
||
|
||
## 🛠️ 服務層架構
|
||
|
||
### 5.1 API 服務設計
|
||
|
||
**統一 API 架構**:
|
||
```typescript
|
||
// lib/services/flashcards.ts
|
||
class FlashcardsService {
|
||
private baseURL = 'http://localhost:5008'
|
||
|
||
// 統一的請求處理
|
||
private async makeRequest<T>(endpoint: string): Promise<ApiResponse<T>>
|
||
|
||
// 業務方法
|
||
async getFlashcards(): Promise<ApiResponse<Flashcard[]>>
|
||
async createFlashcard(data: CreateFlashcardRequest): Promise<ApiResponse<Flashcard>>
|
||
}
|
||
```
|
||
|
||
**優勢**:
|
||
- 統一的錯誤處理機制
|
||
- 類型安全的 API 介面
|
||
- 支援開發/生產環境切換
|
||
|
||
### 5.2 工具函數層
|
||
|
||
**核心工具**:
|
||
- `cefrUtils.ts` - CEFR 等級處理
|
||
- `flashcardUtils.ts` - 詞卡工具函數
|
||
- `testUtils.ts` - 測試相關工具
|
||
|
||
## 📈 性能分析
|
||
|
||
### 6.1 現況評估
|
||
|
||
**優勢**:
|
||
- ✅ 使用 Next.js App Router 的最新優化
|
||
- ✅ Tailwind CSS 的 purge 機制
|
||
- ✅ TypeScript 的編譯時優化
|
||
|
||
**問題識別**:
|
||
- ❌ 缺乏組件記憶化 (React.memo)
|
||
- ❌ 大型組件未進行代碼分割
|
||
- ❌ 圖片資源未優化 (WebP, 響應式)
|
||
- ❌ 無 Service Worker 快取機制
|
||
|
||
### 6.2 Bundle 分析 (推估)
|
||
|
||
**目前 Bundle 大小**:
|
||
- **主應用**:~2.5MB (開發模式)
|
||
- **複習模組**:~800KB
|
||
- **AI生成模組**:~400KB
|
||
- **詞卡模組**:~600KB
|
||
|
||
## 🔧 具體優化建議
|
||
|
||
### 7.1 立即可實施 (本週)
|
||
|
||
1. **組件記憶化**:
|
||
```typescript
|
||
// 高頻重渲染組件加上 React.memo
|
||
export const FlashcardCard = React.memo(FlashcardCard)
|
||
export const VocabularyStatsGrid = React.memo(VocabularyStatsGrid)
|
||
```
|
||
|
||
2. **圖片優化**:
|
||
```typescript
|
||
// 添加圖片懶載入
|
||
<img loading="lazy" src={imageUrl} alt="..." />
|
||
```
|
||
|
||
3. **Hook 合併**:
|
||
```typescript
|
||
// 合併相似的 TTS 播放邏輯
|
||
const useTTSManager = () => {
|
||
// 統一的 TTS 邏輯
|
||
}
|
||
```
|
||
|
||
### 7.2 短期優化 (2-4週)
|
||
|
||
1. **代碼分割**:
|
||
```typescript
|
||
// 路由級別的懶載入
|
||
const ReviewPage = lazy(() => import('./review/page'))
|
||
const GeneratePage = lazy(() => import('./generate/page'))
|
||
```
|
||
|
||
2. **Store 重構**:
|
||
```typescript
|
||
// 拆分大型 Store
|
||
const useTestQueueCore = create(...) // 核心邏輯
|
||
const useTestQueueUI = create(...) // UI 狀態
|
||
```
|
||
|
||
3. **API 快取**:
|
||
```typescript
|
||
// 實施 SWR 或 React Query
|
||
const { data, error, mutate } = useSWR('/api/flashcards', fetcher)
|
||
```
|
||
|
||
### 7.3 中期重構 (1-2月)
|
||
|
||
1. **微前端模組化**:
|
||
```typescript
|
||
// 按功能拆分獨立模組
|
||
apps/
|
||
├── flashcards-module/
|
||
├── review-module/
|
||
├── generate-module/
|
||
└── shell-app/
|
||
```
|
||
|
||
2. **設計系統**:
|
||
```typescript
|
||
// 建立完整的設計系統
|
||
components/
|
||
├── atoms/ # 原子組件
|
||
├── molecules/ # 分子組件
|
||
├── organisms/ # 有機體組件
|
||
└── templates/ # 頁面模板
|
||
```
|
||
|
||
3. **測試體系**:
|
||
```typescript
|
||
// 完整的測試覆蓋
|
||
__tests__/
|
||
├── components/ # 組件測試
|
||
├── hooks/ # Hook 測試
|
||
├── stores/ # Store 測試
|
||
└── e2e/ # E2E 測試
|
||
```
|
||
|
||
## 🎯 架構成熟度評分
|
||
|
||
| 分類 | 評分 | 說明 |
|
||
|-----|-----|------|
|
||
| **組件設計** | ⭐⭐⭐⭐⭐ | 模組化程度高,重用性良好 |
|
||
| **狀態管理** | ⭐⭐⭐⭐ | 分層清晰但複雜度稍高 |
|
||
| **類型安全** | ⭐⭐⭐⭐⭐ | TypeScript 覆蓋率完整 |
|
||
| **性能優化** | ⭐⭐⭐ | 基礎優化到位,進階優化待加強 |
|
||
| **測試覆蓋** | ⭐⭐ | 缺乏完整的測試體系 |
|
||
| **文檔完整** | ⭐⭐⭐ | 基礎文檔存在,詳細文檔不足 |
|
||
| **可維護性** | ⭐⭐⭐⭐ | 架構清晰,但複雜度需控制 |
|
||
|
||
**整體評分**:⭐⭐⭐⭐ (4/5) - **優秀的現代前端架構**
|
||
|
||
## 🔍 深度分析:雙層設計模式
|
||
|
||
### Hook + Store 雙層設計詳解
|
||
|
||
你提到的重點:**為什麼要 Hook 和 Store 兩層?**
|
||
|
||
**實際案例分析**:
|
||
|
||
#### Store 層 (純狀態)
|
||
```typescript
|
||
// useReviewSessionStore.ts
|
||
{
|
||
currentCard: ExtendedFlashcard | null,
|
||
isLoading: boolean,
|
||
setCurrentCard: (card) => set({ currentCard: card }),
|
||
setLoading: (loading) => set({ isLoading: loading })
|
||
}
|
||
```
|
||
|
||
#### Hook 層 (業務邏輯)
|
||
```typescript
|
||
// useReviewSession.ts
|
||
export const useReviewSession = () => {
|
||
const store = useReviewSessionStore()
|
||
|
||
const loadNextCard = async () => {
|
||
store.setLoading(true) // Store 操作
|
||
const result = await flashcardsService.getDueFlashcards() // API 呼叫
|
||
store.setCurrentCard(result.data[0]) // Store 操作
|
||
store.setLoading(false) // Store 操作
|
||
}
|
||
|
||
return { ...store, loadNextCard } // Store + 業務邏輯
|
||
}
|
||
```
|
||
|
||
### 📊 雙層設計的價值
|
||
|
||
**優點**:
|
||
1. **關注點分離**: Store 專注狀態,Hook 專注邏輯
|
||
2. **重用性**: Store 可被多個 Hook 使用
|
||
3. **可測試性**: 可獨立測試狀態邏輯和業務邏輯
|
||
4. **擴展性**: 新功能容易添加新 Hook
|
||
|
||
**缺點**:
|
||
1. **學習成本**: 開發者需理解兩層概念
|
||
2. **複雜度**: 簡單功能可能過度工程
|
||
3. **調試難度**: 狀態流向更複雜
|
||
|
||
### 🤔 是否過度設計?
|
||
|
||
**分析**:
|
||
|
||
**適合雙層的場景**:
|
||
- ✅ 複習系統:複雜狀態 + 複雜邏輯
|
||
- ✅ 詞卡管理:多種操作模式
|
||
- ✅ AI 生成:異步處理 + 狀態追蹤
|
||
|
||
**可能過度的場景**:
|
||
- ❓ 簡單的 UI 狀態管理
|
||
- ❓ 一次性業務邏輯
|
||
- ❓ 純工具函數封裝
|
||
|
||
## 🚨 發現的架構問題
|
||
|
||
### 問題 1: Hook 邏輯重複
|
||
**現象**:多個組件都有相似的 TTS 播放邏輯
|
||
**影響**:代碼重複,維護成本高
|
||
**解決**:✅ 已通過 `BluePlayButton` 組件統一
|
||
|
||
### 問題 2: Store 複雜度過高
|
||
**現象**:`useTestQueueStore` 有 394 行代碼
|
||
**影響**:難以理解和維護
|
||
**建議**:拆分為多個小 Store
|
||
|
||
### 問題 3: 類型定義分散
|
||
**現象**:類型定義在多個地方重複
|
||
**影響**:類型不一致,重構困難
|
||
**建議**:建立統一的類型註冊中心
|
||
|
||
### 問題 4: 缺乏性能優化
|
||
**現象**:沒有 React.memo, lazy loading
|
||
**影響**:不必要的重渲染
|
||
**建議**:實施組件記憶化策略
|
||
|
||
## 🎯 優化路線圖
|
||
|
||
### Phase 1: 立即優化 (1週)
|
||
- [ ] 組件記憶化 (React.memo)
|
||
- [ ] 圖片懶載入
|
||
- [ ] 統一 TTS 邏輯 ✅
|
||
|
||
### Phase 2: 短期優化 (2-4週)
|
||
- [ ] Store 拆分重構
|
||
- [ ] 代碼分割實施
|
||
- [ ] API 快取機制
|
||
|
||
### Phase 3: 中期重構 (1-2月)
|
||
- [ ] 設計系統建立
|
||
- [ ] 測試框架完整化
|
||
- [ ] 性能監控整合
|
||
|
||
### Phase 4: 長期規劃 (2-3月)
|
||
- [ ] 微前端架構
|
||
- [ ] PWA 功能
|
||
- [ ] 國際化支援
|
||
|
||
## 💡 關鍵建議
|
||
|
||
### 建議 1: 簡化狀態管理
|
||
**當前**:Hook + Store 雙層
|
||
**建議**:評估是否需要簡化為單層(對於簡單狀態)
|
||
|
||
### 建議 2: 實施性能優化
|
||
**優先級**:🔴 高
|
||
- 添加 React.memo 到高頻組件
|
||
- 實施路由級代碼分割
|
||
- 圖片和資源優化
|
||
|
||
### 建議 3: 建立測試體系
|
||
**優先級**:🟡 中
|
||
- 單元測試 (Jest + RTL)
|
||
- 整合測試
|
||
- E2E 測試 (Playwright)
|
||
|
||
### 建議 4: 文檔完善
|
||
**優先級**:🟡 中
|
||
- Storybook 組件文檔
|
||
- API 文檔
|
||
- 架構決策記錄 (ADR)
|
||
|
||
## 📋 總結
|
||
|
||
DramaLing 前端架構**整體優秀**,採用現代的分層設計模式,組件化程度高,類型安全性強。
|
||
|
||
**核心優勢**:
|
||
- 清晰的模組分離
|
||
- 良好的開發體驗
|
||
- 強大的功能完整性
|
||
|
||
**改進空間**:
|
||
- 性能優化需要加強
|
||
- 複雜度控制需要平衡
|
||
- 測試和文檔需要完善
|
||
|
||
**推薦策略**:
|
||
採用**漸進式重構**,優先解決性能問題,然後逐步優化架構複雜度,建立完整的測試和文檔體系。
|
||
|
||
---
|
||
|
||
*報告生成時間: 2025-10-01*
|
||
*分析範圍: Frontend 系統完整架構*
|
||
*建議更新頻率: 每月一次* |