Skip to content

Latest commit

 

History

History
283 lines (218 loc) · 7.08 KB

File metadata and controls

283 lines (218 loc) · 7.08 KB

Qwerty Learner 项目架构文档

📦 项目概述

Qwerty Learner 是一款为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件。用户通过键盘输入单词来同时练习英语拼写和打字技能。

🛠️ 技术栈

类别 技术
框架 React 18
构建工具 Vite
语言 TypeScript
样式 TailwindCSS
状态管理 Jotai (原子化状态)
路由 React Router v6
本地存储 Dexie (IndexedDB 封装)
音频 Howler.js
数据分析 Mixpanel
桌面应用 Tauri
测试 Playwright (E2E)

📂 目录结构

qwerty-learner/
├── src/
│   ├── @types/          # TypeScript 类型定义
│   ├── assets/          # 静态资源 (Logo 等)
│   ├── components/      # 全局可复用组件
│   ├── constants/       # 常量定义
│   ├── hooks/           # 全局自定义 Hooks
│   ├── pages/           # 页面组件
│   ├── resources/       # 词库与音频资源配置
│   ├── store/           # Jotai 全局状态
│   ├── typings/         # 类型定义
│   ├── utils/           # 工具函数
│   ├── index.tsx        # 应用入口
│   └── index.css        # 全局样式
├── public/              # 公共静态资源 (词库 JSON)
├── src-tauri/           # Tauri 桌面应用配置
├── tests/               # E2E 测试
└── scripts/             # 构建/安装脚本

🏗️ 核心架构

路由结构

graph LR
    A["/"] --> B["TypingPage<br/>主练习页面"]
    A --> C["/gallery"]
    C --> D["GalleryPage<br/>词库选择"]
    A --> E["/analysis"]
    E --> F["AnalysisPage<br/>数据分析"]
    A --> G["/error-book"]
    G --> H["ErrorBook<br/>错词本"]
    A --> I["/mobile"]
    I --> J["MobilePage<br/>移动端提示"]
Loading

状态管理架构

采用 Jotai 原子化状态管理,分为两层:

graph TB
    subgraph "全局状态 (src/store)"
        A["currentDictIdAtom<br/>当前词库 ID"]
        B["currentChapterAtom<br/>当前章节"]
        C["pronunciationConfigAtom<br/>发音配置"]
        D["keySoundsConfigAtom<br/>按键音效"]
        E["isOpenDarkModeAtom<br/>暗黑模式"]
        F["wordDictationConfigAtom<br/>听写模式"]
    end
    
    subgraph "页面状态 (Typing/store)"
        G["TypingContext + useImmerReducer<br/>练习状态机"]
    end
    
    A --> G
    B --> G
Loading

Typing 页面状态机

Typing 页面使用 useImmerReducer 管理复杂的练习状态:

interface TypingState {
  chapterData: {
    words: Word[]
    index: number     // 当前单词索引
  }
  inputWord: string   // 用户输入
  isTyping: boolean   // 是否正在练习
  isFinished: boolean // 章节是否完成
  timerData: {
    time: number      // 练习时长
  }
  // ... 更多状态
}

🧩 核心模块

1. 组件层 (src/components/)

组件 功能
Header/ 顶部导航栏
Footer/ 底部信息栏
Layout.tsx 页面布局容器
WordPronunciationIcon/ 单词发音图标
ui/ 基础 UI 组件 (Radix UI)
DonateCard/ 捐赠提示卡片

2. 页面层 (src/pages/)

页面 路径 功能
Typing/ / 核心练习页面,包含单词面板、键盘输入、进度显示
Gallery-N/ /gallery 词库和章节选择界面
Analysis/ /analysis 练习数据统计与可视化 (ECharts)
ErrorBook/ /error-book 错词本管理

3. Typing 子组件 (src/pages/Typing/components/)

Typing/components/
├── WordPanel/         # 单词显示面板
├── WordList/          # 单词列表侧边栏
├── DictChapterButton/ # 词库/章节选择
├── Speed/             # 速度与正确率显示
├── ResultScreen/      # 章节完成结果页
├── Switcher/          # 功能开关面板
├── StartButton/       # 开始按钮
└── PronunciationSwitcher/ # 发音切换

4. 自定义 Hooks (src/hooks/)

Hook 功能
useKeySounds 按键音效播放
usePronunciation 单词发音控制
useSpeech 语音合成 (TTS)
useWindowSize 窗口尺寸监听

5. 数据持久化 (src/utils/db/)

使用 Dexie 封装 IndexedDB:

文件 功能
index.ts 数据库初始化与表定义
record.ts 练习记录 CRUD
review-record.ts 复习记录管理
data-export.ts 数据导入/导出

6. 资源配置 (src/resources/)

文件 功能
dictionary.ts 词库元数据注册 (CET4/6, GRE, 程序员词汇等)
soundResource.ts 音效资源配置

📊 数据流

sequenceDiagram
    participant U as 用户
    participant T as TypingPage
    participant S as Jotai Store
    participant D as Dexie DB
    participant A as 音频服务
    
    U->>T: 选择词库/章节
    T->>S: 更新 currentDictIdAtom
    T->>T: 加载单词列表
    
    U->>T: 开始输入
    T->>T: dispatch(SET_IS_TYPING)
    T->>A: 播放单词发音
    
    U->>T: 输入字符
    T->>T: 验证输入
    T->>A: 播放按键音效
    
    T->>T: 单词完成 → 下一个
    
    T->>T: 章节完成
    T->>D: 保存章节记录
    T->>T: 显示结果页
Loading

⚙️ 构建配置

Vite 配置亮点

  • 路径别名: @src/
  • Jotai 插件: Debug Label + React Refresh
  • 图标按需加载: unplugin-icons
  • Bundle 分析: rollup-plugin-visualizer
  • 生产优化: 移除 console/debugger

部署方式

  1. Vercel (推荐) - 自动部署
  2. GitHub Pages - 需配置 --base=./
  3. Docker - 提供 Dockerfile

📝 词库格式

词库文件位于 public/dicts/,JSON 格式:

[
  {
    "name": "example",
    "trans": ["示例"],
    "usphone": "/ɪɡˈzæmpəl/",
    "ukphone": "/ɪɡˈzɑːmpəl/"
  }
]

🔑 关键设计决策

  1. 原子化状态 (Jotai): 避免不必要的重渲染,配置状态持久化到 localStorage
  2. IndexedDB 存储: 支持大量练习记录的本地存储
  3. Reducer 模式: Typing 页面复杂状态使用 useImmerReducer 管理
  4. 音频预加载: Howler.js 管理按键音效和发音
  5. 响应式设计: 桌面端优先,移动端显示提示页

🚀 开发命令

# 安装依赖
yarn install

# 开发模式
yarn dev

# 构建生产版本
yarn build

# 运行 E2E 测试
yarn test:e2e

# 代码检查
yarn lint

📁 相关文件索引

功能 文件路径
应用入口 src/index.tsx
全局状态 src/store/index.ts
Typing 主页 src/pages/Typing/index.tsx
词库配置 src/resources/dictionary.ts
数据库封装 src/utils/db/index.ts
Vite 配置 vite.config.ts