当前位置: 首页 > news >正文

前端项目:SpeakMentor AI 场景化英语口语陪练助手开发复盘

这是我第一次比较完整地按照真实项目开发流程完成一个前端项目。

在开始这个项目之前,我对 React、TypeScript、Vite、Ant Design 这些技术栈有一定了解,也能看懂单个组件、单个函数的语句含义。但是当真正要从 0 开始做一个项目时,我发现困难并不只是“某一行代码怎么写”,而是:

  • 如何分析一个项目需求?
  • 如何把一个大功能拆成多个小功能?
  • 文件应该怎么分?
  • 数据结构应该怎么设计?
  • 前端和后端如何联调?
  • Git 分支和 PR 应该怎么管理?
  • 最后如何整理 README 和项目材料?

这篇博客主要记录我从需求分析、技术选型、功能拆分、开发实现、前后端联调,到最后项目提交的完整过程。它更适合和我一样刚开始做项目的前端初学者,希望可以给大家一个参考。

项目地址:[SpeakMentor AI](https://github.com/tongxin02ssd-blip/speakmentor-ai)

一、项目想法和需求分析

这个项目的想法来自英语口语练习场景。很多英语学习者不是完全不会英语,而是缺少真实对话环境,说完之后也不知道自己哪里表达得不自然。所以我希望做一个 AI 口语陪练工具,让用户可以选择面试、点餐、会议等真实场景,通过语音输入英文,系统再给出 AI 回复、语法纠错、自然表达建议、发音反馈和量化评分。

刚开始做需求分析时,我没有急着写代码,而是先想清楚这个项目到底要解决什么问题。它的核心不是做一个普通聊天框,而是形成一次完整的口语练习体验。用户选择一个场景,说一句英文,系统识别用户表达,AI 根据场景回复,同时给出这句话的纠错、发音建议和评分。这样项目的主线就比较清楚了。

因此,我把项目的最小可行版本确定为:用户能够选择一个场景,输入或模拟输入一句英文,系统生成 AI 回复,并展示对应的纠错反馈和评分。先把这个主流程跑通,再逐步加入真实语音识别、语音播报、后端接口和大模型 API。

二、技术选型和项目架构

技术栈方面,前端使用 React、TypeScript、Vite 和 Ant Design。React 负责构建页面,TypeScript 用来约束数据结构,Vite 用来快速启动项目,Ant Design 用来提高 UI 开发效率。语音识别部分使用浏览器的 Web Speech API,AI 回复播报使用浏览器内置的 SpeechSynthesis。后端使用 Node.js、Express 和 TypeScript,主要负责接收前端请求、调用大模型接口,并在没有 API Key 或接口失败时返回 Mock 数据。

项目采用前后端分离结构。前端主要负责页面展示、用户交互、语音输入、状态管理和接口调用;后端主要负责处理对话请求、调用 AI 服务、生成结构化反馈,并提供 Mock fallback。

前端目录中,components主要放页面组件,比如场景选择、语音输入、对话展示和反馈展示。它们更偏向展示层,不负责太复杂的业务逻辑。App.tsx是整个前端项目的流程控制中心,负责维护当前场景、对话消息、语音识别状态、AI 回复状态、纠错反馈和评分结果。刚开始看到App.tsx里有很多状态会觉得乱,但如果按业务分组去理解,它其实就是整个项目的数据调度中心。

types用来定义核心数据结构,比如一条对话消息、一次纠错反馈、一组评分结果。mocks用来生成前端 Mock 数据,在没有真实接口时保证项目可以运行。hooks用来封装浏览器能力,比如语音识别和语音播报。api用来封装 Axios 请求,让组件不需要直接关心后端地址。utils则放一些通用工具函数,例如创建对话消息、计算评分等级等。

后端目录也按职责拆分。routes定义接口地址,controllers处理请求参数和响应,services负责业务逻辑。后端提供了/health健康检查接口和/api/dialogue对话接口。前端把用户输入的英文文本发给后端,后端再返回 AI 回复、纠错反馈、发音建议和评分结果。为了后续接入真实大模型,我又单独加了aiServicepromptService,分别负责大模型请求和 Prompt 构造。

三、开发过程和功能拆分

这个项目我没有一次性写完,而是按照 PR 拆分来完成。第一个 PR 只做项目初始化,第二个 PR 搭建页面布局,后面再逐步实现场景选择、Mock 数据结构、对话记录展示、语音输入、AI 回复、纠错反馈、评分面板、语音播报、后端服务和前后端联调。

这样的开发方式对初学者很友好。因为每次只做一个小功能,出问题时也更容易定位。例如在语音输入功能还没有接入真实浏览器 API 之前,我先做了 Mock ASR,让按钮点击后可以生成一段模拟英文文本。这样可以先把页面和数据流跑通,再逐步替换成真实能力。

项目的核心交互是用户完成一次口语练习。用户先选择练习场景,然后点击按钮进行语音输入。前端拿到识别文本后,会生成一条用户消息并展示在对话区,同时请求后端/api/dialogue接口。后端根据场景和用户输入返回 AI 回复、纠错反馈和评分结果。前端收到结果后,把 AI 回复追加到对话区,并在右侧反馈区展示语法纠错、自然表达、发音建议和量化评分。

这个过程中,最关键的不是某个组件怎么写,而是要理解数据怎么流动。以前我总是盯着单个文件看,觉得每一行代码都能看懂,但合起来还是不知道项目怎么运行。后来我发现,理解项目应该从用户操作出发。只要能讲清楚用户点击之后,哪个组件触发事件,App.tsx里哪个函数处理,数据如何生成,接口如何请求,结果如何展示,整个项目就会清楚很多。

四、Mock 和 fallback 设计

这个项目里我觉得最重要的设计是 Mock fallback。因为 AI 项目在演示时很容易遇到不稳定因素,比如浏览器不支持语音识别、麦克风权限失败、后端没启动、API Key 没配置、大模型接口请求失败等。如果没有兜底方案,Demo 很容易中断。

因此我在项目里保留了多层 Mock。真实语音识别失败时,可以自动使用前端 Mock ASR;后端真实 AI 调用失败时,会自动返回后端 Mock;如果后端服务没有启动,前端也会自动降级到本地 Mock。这样即使外部条件不稳定,项目的核心流程仍然可以完整演示。

这个设计也让我意识到,项目开发不能只考虑理想情况。真实项目里,接口可能失败,浏览器能力可能不兼容,用户权限可能被拒绝。一个体验比较完整的项目,应该在失败时也能给用户清晰的反馈,并尽量保证主流程不中断。

五、Git、README 和项目提交

这个项目我尽量采用分支和 PR 的方式开发,而不是直接在 main 分支上不断修改。每个功能新建一个分支,每个 PR 只做一件事,并在 PR 描述里写清楚功能描述、实现思路和测试方式。这样不仅方便自己回顾,也能让提交记录更规范。

README 也是项目提交里很重要的一部分。一个项目如果只有代码,没有说明,别人很难快速理解你做了什么。我在 README 中整理了项目简介、核心功能、技术栈、启动方式、环境变量配置、Mock 模式说明和后续优化方向。尤其是 AI 项目,更要说明没有 API Key 时是否可以运行,后端服务如何启动,接口失败时是否有 fallback。

通过这个过程,我发现“项目完整度”不仅体现在功能数量上,也体现在项目是否能被别人顺利运行和理解。代码能跑是一方面,别人能看懂项目定位、启动方式和核心流程,也同样重要。

六、我的收获和给初学者的建议

通过 SpeakMentor AI 这个项目,我最大的收获不是学会了某一个 API,而是第一次比较完整地体验了前端项目从 0 到 1 的开发过程。它让我意识到,项目能力和语法能力是不一样的。语法能力是知道代码怎么写,项目能力是知道为什么要这样拆分、数据为什么这样流动、文件为什么这样组织,以及功能失败时应该怎么兜底。

如果你也是刚开始做前端项目,我的建议是不要一开始就追求很大的项目,也不要只停留在看教程。可以选择一个小而完整的主题,先把主流程跑通,再一点点补充功能。先用 Mock 数据完成页面和交互,再逐步接入真实 API。这样既不会一开始就被复杂技术劝退,也能比较完整地体验项目开发流程。

做项目时,也不要只盯着某个文件逐行看。更有效的方式是从用户操作出发,思考这个操作会触发哪个函数,数据会保存在哪里,会传给哪个组件,最后显示在页面的什么位置。当你能讲清楚这个过程时,你就不只是“跟着代码写”,而是真的开始理解前端工程了。

第一个项目最重要的不是代码多高级,而是完整走完一遍。从需求分析、页面设计、组件拆分、Mock 数据、接口联调,到 README 和 GitHub 提交,每一步都会让你对前端开发有更具体的认识。走完之后再回头看 React、TypeScript、组件拆分和接口请求,会比单纯刷语法题理解得更深入。

http://www.jsqmd.com/news/973375/

相关文章:

  • 保姆级避坑指南:SAP SPRO中给公司代码分配采购组织,新手最容易搞混的几点
  • Nsight System + Nsight Compute 组合拳:从宏观Timeline到微观Counter的CUDA应用全链路性能分析实战
  • 深入涂鸦Wi-Fi模组协议栈:手把手解析MCU与模组间的数据帧(含心跳、配网、OTA全流程)
  • XUnity.AutoTranslator字体管理实战指南:如何解决Unity游戏多语言显示难题
  • 别再只用System.out.printf了!Java保留小数点的3种方法实战对比(含DecimalFormat避坑)
  • 淮北矿业股息率怎么这么高,未来预期产能能翻倍吗?
  • 别再乱调学习率了!用PyTorch的CosineAnnealingLR和WarmRestarts,让你的模型训练又快又稳(附完整代码)
  • Qt 高级开发 028:以代码为笔,以界面为卷
  • 别再只会升级GCC了!遇到‘unrecognized command line option‘的三种排查思路与降级方案
  • 多维聚合实战:从SQL GROUP BY到OLAP立方体的工程跃迁
  • 2026 安徽淮北市|本地人必选旧房改造・墙面刷新・局部装修 3 家正规企业精选 + 避坑攻略 - 本地便民网
  • MounRiver工程配置避坑指南:从零配置沁恒MCU头文件、库路径与Linker Script
  • Android启动安全实战:手把手教你用avbtool给dtbo.img镜像签名(附源码分析)
  • 告别环境配置噩梦:用Docker镜像5分钟搞定OpenFPGA开发环境(Ubuntu 20.04实测)
  • Mythos能力解析:跨步状态锚定与长程推理一致性技术
  • NTC温度采集全套开发资源:单片机驱动+查表工具+上位机显示+硬件设计文件
  • PSCAD仿真效率提升技巧:从元件布局、参数复用到底层波形导出全流程优化
  • 从需求到代码:手把手教你用PlantUML插件,在IDEA里自动生成时序图和类图
  • IT项目管理的难点在哪里?
  • 创维E900V21C救砖记:从TTL跑码异常到飞线修复,手把手教你排查硬件短路
  • 寄件不用跑腿!手机一键下单,大小件全部上门取件 - 时讯资讯
  • Quartus 18.1 + DE10-Lite开发板:保姆级图文教程,带你跑通第一个NIOS II程序
  • OBD诊断协议揭秘:ISO15031 $02服务如何让ECU‘冻结’故障瞬间(附PID速查表)
  • tidevice不只是安装启动:这5个隐藏功能让iOS测试效率翻倍
  • CPU核心没跑满?7大真实瓶颈与实操优化指南
  • 别再死记硬背UML图了!用这3个真实项目案例,带你搞懂用例图、活动图与类图怎么画
  • 告别裸机:在STM32CubeIDE中为STM32H7集成SOEM 1.4.0的完整配置流程
  • PHP高精度计时器与性能基准
  • 智慧农业AI+DeepSeek的病虫害检测与环境监测一体化智能云平台
  • 别再搞混了!Android布局中margin和padding的实战避坑指南(附ConstraintLayout案例)