我是做前端开发的,早些年也做过 UI。这些年因为工作和个人项目的关系,后端、数据库和服务器也一直在接触,但真要一个人把前端、API、数据迁移和部署全部串起来,还是很费精力。不是其中某一块不会做,而是脑子要不停地切换。
这次重做航栈,我把 Codex 放进了整个开发过程。它不只是帮我补几个组件,而是参与了代码梳理、功能实现、数据脚本、测试和部署文档。
从 Git 记录来看,第一个项目基线提交是在 8 月 9 日,生产环境配置在 8 月 17 日落地,核心重构刚好 9 天。
航栈本身已经运行了很多年,产品怎么做、页面长什么样、哪些数据必须保留,这些我心里都有答案。我没有指望输入一句话就等着网站生成,主要是让 Codex 接手那些需要来回翻代码、改文件和跑检查的工作。
先说说我重做了什么
航栈的旧版本是 2019 年重写的,技术栈是 Vue 2、Webpack 4、ThinkPHP 5 和 MySQL。
那套代码陪了我五年多。文章、网址导航、社区、评论、收藏、个人中心和升级日志,都是后来一点点加进去的。当时为了 SEO,我还做过一套比较折中的方案:Vue 负责页面交互,ThinkPHP 先查数据库,再把标题、关键词和描述注入打包后的 HTML 模板。
这个方案在当时能用,但时间久了以后,继续维护已经不太舒服。Vue 2 和旧依赖越来越难升级,前后端类型完全分开,公开页面的 SEO 逻辑也散落在不同位置。
新版本换成了下面这套结构:
前端:Nuxt 4 + Vue 3 + TypeScript
后端:NestJS 11 + Fastify 5
数据:Prisma + MySQL 8 + Redis
工程:pnpm Workspace + Turborepo
部署:Nginx + PM2
现在的航栈也不只是一个博客。除了文章阅读和发布,还有工具发现、社区、用户主页、评论收藏、图片上传、内容审核、举报、后台管理、搜索、订阅和访问统计。
写这篇文章时,我顺手统计了一下仓库:主要源码文件 151 个,大约 3.6 万行;前端有 20 个页面文件,后端有 8 个 Controller,Prisma 里有 30 个数据模型和 12 次迁移。
列这些数字不是为了展示代码量,只是交代一下项目规模:我处理的不是空目录里的 Demo,而是一个准备继续长期维护的网站。
航栈正式站的“发现”页,截图于本文发布前。
我为什么会用 Codex 来做这次重构
以前我也用过各种 AI 编程工具,最常见的用法是:复制代码过去,问它哪里有问题,再把回复复制回来。
小问题这样做没什么,但项目一大就很累。比如修改文章发布流程,前端表单、状态管理、接口 DTO、数据库字段和后台审核都有关系。只贴一个 Vue 文件,AI 很难知道其他地方发生了什么。
Codex 对我最有用的地方,是它可以直接读整个项目,也可以自己去找相关文件。我要改一个功能时,不需要先手动把十几个文件整理好再喂给它。它可以顺着页面找到 composable,再找到 API Controller、Service 和 Prisma 模型,改完以后继续跑类型检查和构建。
所以我给它的任务一般不是“帮我写一段代码”,而是“把这个问题在当前项目里处理完”。
但我也不会一上来就让它大改。项目刚开始时,我先让它只读代码,不动文件,把旧站有哪些页面、接口和数据实体梳理出来,再讨论哪些东西应该保留,哪些可以趁这次机会重新设计。
这一步当时花了一些时间,后面却少了很多返工。它还没看懂项目时,我不太敢让它直接动手,否则很可能改完一个地方,又得去另外几个地方补洞。
我没有一次把所有需求都扔进去
重构最容易犯的错,就是先铺一堆页面,再铺一堆接口,最后才联调。表面上进度很快,真正打开页面时却全是模拟数据。
我这次基本按一条条完整链路往下做。
最先打通的是公开文章:Prisma 从 MySQL 读取文章,NestJS 提供接口,Nuxt 在服务端请求数据,再输出包含真实标题和正文的 HTML。文章列表、文章详情和 404 都跑通以后,才继续做账号、创作和媒体上传。
后面的 Git 提交也能看出这个顺序:先建立项目基线,然后让公开文章接上数据库,接着做账号和发布 API、创作端页面、生产准备,最后补内容审核和环境配置。
我通常会把任务说得比较具体,例如文章详情页这一轮,我会这样写:
重构文章详情页,公开内容继续走 SSR。
正文是页面主体,作者、目录和相关推荐都是辅助信息。
不要改现有文章接口;桌面端控制正文宽度,移动端收起侧栏;
继续使用现有设计变量。
完成后检查长标题、图片、Markdown 和代码块,
并确认 SSR 返回的 HTML 里能找到文章标题,最后跑类型检查和构建。
这和写一份很正式的需求文档不是一回事。我只是尽量把“不能改什么”和“怎样算完成”说清楚。
如果只说“帮我把文章页做得高级一点”,Codex 也会写,但结果很容易变成一堆卡片、渐变和大圆角。看上去什么都有,就是不像我的网站。
文章详情页的一版设计方案。我会先确定阅读宽度、目录和作者信息的主次,再让 Codex 往代码里落。
前端这部分,我还是会盯得很细
我本职是前端,以前也做过 UI,所以页面不可能生成一次就算结束。
这次首页、登录、文章列表、文章详情、工具详情、创作台和个人主页都做过多版设计。项目里的设计图文件名带着 v1、v2、v3,有的页面甚至改到了 v7。
首页曾经尝试过深色编辑精选风格,后来又根据真实内容和整体品牌继续调整。
Codex 写布局、组件和响应式样式的速度很快,但“能还原”不等于“看着舒服”。这部分我还是会自己看截图,告诉它哪里有问题。
我很少再说“优化一下”,而是直接指出:
- 首屏留白太多,文章标题被压到下面了;
- 侧栏视觉太重,注意力从正文跑掉了;
- 卡片边框太多,整个页面像管理后台;
- 移动端按钮挤在一起,主要操作不够明显;
- 字号没问题,但标题和摘要之间的层级不够。
反馈越具体,它下一轮改得越准。
创作者主页改到第七版时,信息层级和航栈现在的视觉语言才慢慢统一起来。
不过我也踩过一个很明显的坑:让 Codex 连续改很多轮 CSS 后,局部样式很容易越堆越多。后来我会在一轮页面确认后,让它回头检查重复规则、无效选择器和可以收进设计变量的值,而不是只顾着把截图改得像。
对前端开发来说,这一点应该很熟悉。页面迭代快的时候,最先失控的往往不是业务逻辑,而是那些“先加一行,后面再整理”的样式。
真正省时间的,是数据迁移和那些工程脚本
如果只看页面,可能会觉得 Codex 最大的价值是写组件。但这次最帮我省时间的,反而是历史数据处理。
旧站里有多年的文章、图片、工具数据和升级日志。它们来自不同阶段,字段和内容格式并不完全一样。有些正文是 HTML,有些图片地址已经换过,还有一些发布时间、分类和摘要需要重新整理。
这种事情手工做很枯燥,而且很容易漏。
我让 Codex 把迁移拆成几步:先读取和清洗,输出待审核的数据和报告;我确认后再预览导入;最后才真正写进数据库,并核对导入前后的数量。
项目里现在有不少这样的脚本:
- 整理旧文章,输出 Markdown 和图片清单;
- 导入审核后的文章;
- 迁移历史升级日志;
- 检查工具链接是否还能访问;
- 审核资源描述里混入的英文;
- 清理过期会话、验证码和访问明细。
我对数据操作一直比较谨慎。预览可以直接跑,真正导入、覆盖或者删除必须单独确认。Codex 可以帮我写脚本,也可以把核对项列得很完整,但最终按下执行的那一步,我不会交给一句模糊的指令。
数据库出问题,和页面边距改错不是一个级别。
SSR 不能只靠“浏览器里看着正常”
这次换 Nuxt,一个主要原因就是想把公开内容的 SSR 和 SEO 做得更干净。
旧站为了让搜索引擎拿到标题和描述,需要在 ThinkPHP 控制器和 Vue 页面之间绕一层。新站里,文章、工具和社区详情直接在 Nuxt 服务端取数据,页面内容、Meta、Canonical、Open Graph 和结构化数据都从同一份内容生成。
登录、个人中心、创作台和后台这些不需要收录的页面,则明确加上 noindex。后台因为登录状态保存在浏览器端,干脆关闭 SSR,避免服务端输出不该出现的受保护内容。
这些逻辑用浏览器点几下很难完全确认,所以我让 Codex 补了 SSR 冒烟测试。
测试会启动生产构建后的 Web 和 API 服务,读取数据库里的真实文章、工具和社区内容,然后请求对应页面。除了检查状态码,还会确认返回的是完整 HTML,并且详情页里确实包含数据库中的标题。
项目最后保留了几条固定检查命令:
pnpm typecheck
pnpm build
pnpm smoke:content
pnpm smoke:ssr
Codex 每完成一个阶段,我都会让它跑相应检查。它说“已经完成”不算完成,命令真的通过、页面也符合预期,才算这一轮结束。
上线这件事,我没有让它自由发挥
开发环境跑起来以后,还有 Nginx、PM2、MySQL、Redis、SMTP、上传目录、备份和 HTTPS。
这部分 Codex 帮我整理了很长的部署文档,也检查过生产环境变量和反向代理配置。API、Nuxt SSR 和上传文件分别走哪个地址,PM2 启动哪些进程,数据库迁移前怎么备份,构建失败后怎么办,都写进了仓库。
其中有一条规则很简单:类型检查、构建或迁移只要有一步失败,就停止发布,不要继续重载 PM2。
因为生产环境不是试错场。代码改坏了还能回退,数据库和用户上传文件如果处理错了,恢复成本会高很多。
所以我会让 Codex 帮我检查、执行明确的步骤和整理输出,但涉及数据库恢复、删除文件、覆盖正式数据时,目标和路径都必须再次确认。
用下来以后,我对 Codex 的真实感受
它确实让我一个人的开发速度快了很多,尤其是跨前端、后端和脚本的任务。以前改一个完整功能,我要不断在页面、接口和数据模型之间切换;现在可以先把目标说清楚,让它去追踪相关代码,我把精力更多放在产品判断和最终验收上。
但它也没有神奇到可以不管。
需求说得太大,它会一下改很多文件,审查起来反而麻烦;设计反馈太抽象,它会套常见的视觉风格;测试覆盖不到的地方,它也可能很自信地认为没有问题。
我现在比较习惯的方式是:先让它读项目,再给一个边界明确的任务;做完后看 diff、跑检查、看页面;有问题就描述实际现象,而不是继续追加一句“再优化”。
还有一点很重要:我的前端经验没有因为使用 Codex 变得不重要,反而更重要了。
我得知道 SSR 为什么这样做,才能判断它的实现对不对;我得知道组件和样式应该怎么组织,才能发现页面虽然还原了,但代码已经开始变乱;我也得理解接口、数据库和部署,才敢让它继续往下做。
所以用到后面,我越来越愿意让它多做,但需要我判断的地方其实一点也没少。
写在最后
九天当然做不出一个网站过去五年的内容和积累。Codex 帮我完成的,是把这些已经存在的东西搬到一个新的技术底座上,并把以前想做但一直没有时间整理的工程问题一起补上。
这次重构让我最舒服的地方,是以后再加一个功能,不用先绕过五年前留下的那堆限制。至于生成了多少代码,反而没有那么重要。
现在的航栈还会继续改。我也会继续把它当成自己的长期项目,写文章、收集好用的开发工具,偶尔折腾一些不一定有用但自己很想做的功能。
如果你也是前端开发,手里刚好有一个拖了很久的个人项目,可以试着把 Codex 当成一个能直接进仓库干活的搭档。先给它一个小而完整的任务,看看它能不能把页面、接口和验证一起跑通。
不要从“一句话做完整个项目”开始。那样通常看起来很快,最后还是你自己收拾。