前端项目: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 回复、纠错反馈、发音建议和评分结果。为了后续接入真实大模型,我又单独加了aiService和promptService,分别负责大模型请求和 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、组件拆分和接口请求,会比单纯刷语法题理解得更深入。
