一个人、一台电脑、一个 AI 编码助手,怎么把一个 web 产品从"能看"做到"能用",再做到"好用"?。
为什么要写这篇文章
AI 编码工具把"写代码"的成本压到了接近零。现在一个人一天就能搭出一个完整的前后端应用,这在三年前是不可想象的。
但问题也来了:当生成代码不再是瓶颈,工程基本功就成了新的瓶颈。AI 帮你快,不帮你稳。如果你只享受了"快"的部分,三个月后你会面对一个自己都看不懂的代码库。
这篇文章不讲"AI 怎么用"。讲的是在 AI 帮你加速的前提下,哪些工程实践仍然必须做、为什么做、做了能换来什么。
一、仓库结构:为什么一个仓库就够了
做法:前端、后端、文档放在同一个 monorepo,分 frontend/、backend/、docs/ 三个目录。不要用 turbo、nx、pnpm workspace 这些工具。
为什么:
独立开发者最容易在仓库结构上走两个极端。要么前端一个仓库、后端一个仓库、文档一个仓库,改一个接口要开三个编辑器同步;要么上来就上 monorepo 工具链,配了一天 turbo 还没写出一行业务代码。
分仓库的问题在于原子性。一个接口从"后端改字段"到"前端改调用"到"文档更新",应该是一个 commit。分三个仓库意味着你永远在不同步,永远在"改了 A 忘了 B"。
工具链的问题在于成本不匹配。turbo 和 nx 是给多包、多应用、共享内部 npm 包的大仓库设计的。你只有一个前端一个后端,引入它们只会让你多学一个配置文件,没有任何收益。
收益:改一个功能时,前后端和文档天然在同一个 commit 里。AI 也能同时看到前后端代码,不会写出前端调 /api/wrong-path 这种它自己都发现不了的 bug。
二、测试:为什么不追覆盖率,只追"敢推"
做法:前端测纯函数(日期计算、数据转换、冲突处理),不测 DOM。后端测业务逻辑(接口正常路径和边界情况),不测 CRUD 样板代码。目标是跑一条 make test 能确认核心路径没坏。
为什么:
独立开发者在测试上最容易走两个极端。要么完全不写,改完靠手点,上线靠运气;要么上来就追 80% 覆盖率,花一周写测试,产品还没上线就倦怠了。
覆盖率是一个指标,但它不是目标。目标是"我改完代码后,有没有信心推上去"。这个信心来自哪里?来自你知道"如果我改坏了某个核心逻辑,测试会红"。
DOM 渲染不需要测——浏览器比你可靠。CRUD 样板不需要测——框架比你可靠。你需要测的是你自己写的业务判断:日期对不对、冲突怎么合并、幂等键怎么处理。这些东西写错了不会报错,只会悄无声息地产生脏数据。
收益:你敢重构了。以前改一段代码要在脑子里推演十遍,现在跑一条命令 2 秒出结果。这个心理释放比覆盖率数字重要得多。
三、CI:为什么 5 分钟的投入换无数个凌晨
做法:GitHub Actions 跑 lint + 测试 + 构建,push 上去 2 分钟出结果。
为什么:
没有 CI 时,你唯一的验证方式是"本地跑一遍,然后赌"。但本地跑的时候你可能忘了跑前端、忘了跑后端、忘了在干净环境里装依赖。CI 把这些变成确定性:push 上去,绿了就是真的绿了。
lint 的价值经常被低估。它不是"代码风格检查",它是最便宜的 bug 过滤器——未使用的变量、拼错的字段、不可能为真的条件,这些东西 lint 能在 1 秒内抓住,而你人工 review 可能要花 10 分钟还漏。
收益:你不用再凌晨三点爬起来看线上为什么挂了。CI 红了,你在喝咖啡的时候就知道了。这个心理安全感是无价的。
四、给 AI 写一份"工作说明书"
做法:仓库根目录放一个 AGENTS.md,写清楚:项目是什么、改代码去哪个目录、常用命令是什么、不要碰什么。
为什么:
这是 AI 时代独有的问题。传统开发里,新同事入职有 onboarding,有 code review,有人问。但 AI 每次启动都是失忆的——它不知道你的项目结构、不知道你的约定、不知道你不想让它动哪些文件。
没有这份文件,AI 第一次接触项目会做什么?它会 find . 扫一遍整个仓库,吃掉你几千 token;不小心读了你 3 万字的产品文档,然后根本用不上;改完代码不知道要跑测试,直接说"完成了"。
这份文件不需要长。20 行就够:项目一句话、目录地图、三条命令、五条禁忌。
收益:AI 第一次接触你的项目就少犯 80% 的错。你不需要每次重复"别读 docs/""改完跑测试""别引入新框架"。它自己会看。
五、错误监控:为什么上线第一天就要有
做法:前端接 Sentry 免费版,DSN 走环境变量,没配就自动禁用。后端用框架自带的 panic recovery + 堆栈日志。
为什么:
独立开发者最孤独的时刻是用户说"用不了",你打开日志发现什么都没有。没有错误监控,你只能靠"用户截图"和"自己猜"。
很多人觉得"现在用户少,等多了再加"。但加监控的成本是固定的——10 分钟。等你出了第一个线上 bug 再加,成本就不是 10 分钟了,是通宵查日志。
Sentry 的设计很友好:没配 DSN 就静默禁用,不影响功能。所以你可以代码先写好,DSN 以后再填。
收益:线上出问题时,你直接看到堆栈、用户路径、浏览器版本。不是猜。
六、数据库迁移:为什么别让 ORM 替你做 schema 决策
做法:每次改表结构写一个版本化 SQL 文件(000002_add_user_avatar.up.sql),应用启动时自动跑 migration。不要用 ORM 的 AutoMigrate。
为什么:
ORM 的 AutoMigrate 在开发期是魔鬼。它确实爽——一行代码建表,不用手写 SQL。但问题在于:
- 生产上你想改个字段类型,它悄悄改了,可能丢数据
- 三个月后你不知道这个表有多少列是历史遗留
- 你没有任何"这次改表做了什么"的记录
版本化 migration 的核心不是工具,是纪律:每一次 schema 变更都有一个文件,文件名带版本号,内容是确定的 SQL。你可以 review、可以回滚、可以在另一个环境复现。
收益:你敢改数据库了。以前改个字段要备份、要在测试库试、要小心翼翼。现在就是写一个 SQL 文件,跑 migration,看结果。
七、文档:为什么只写"以后你自己看不懂"的部分
做法:只写三类文档——API 契约、架构决策、部署手册。不要写代码的复述,不要写日常 TODO。
为什么:
独立开发者在文档上最容易走两个极端。要么完全不写,三个月后自己都忘了为什么这么设计;要么写太多,把所有代码都复述一遍,改代码时文档就过时了。
文档的价值不在于"写了多少",在于"三个月后你回来时,能不能快速想起来"。代码你读一遍就知道它做了什么,但代码不会告诉你为什么——为什么选 A 不选 B、为什么这个字段加了索引、为什么这个接口要做幂等。
这些"为什么"才是文档该存在的理由。
收益:你维护自己代码的成本从"重新理解一遍"降到"读三行回忆起来了"。
八、为什么不要过度工程
做法:不要微服务、不要 K8s、不要 monorepo 工具链、不要 GraphQL、不要事件驱动架构。什么时候升级?有明确触发条件。
为什么:
独立开发者最大的风险不是技术不够,是技术太多。看到大厂博客就想抄,最后花在搭架子上的时间比写产品还多。
这些技术每一个单独看都"对",但它们解决的问题你都还没有遇到。微服务解决的是团队协作问题,你只有一个人;K8s 解决的是运维规模问题,你只有一台 VPS;GraphQL 解决的是前端需求多变问题,你只有一个前端。
收益:你的全部时间都花在用户能感知的东西上。没有"我花了一周配 CI/CD 但用户根本不知道"这种沉没成本。
九、部署:为什么能 scp 就不要搞 CI/CD
做法:本地 build,scp 到服务器,systemctl restart。听起来很原始。
为什么:
CI/CD pipeline 有它的价值,但对独立开发者来说,它的调试成本经常大于自动化收益。50 行 YAML 挂了,你要花一个下午搞清楚是缓存问题还是权限问题。
手动部署的好处是透明。你知道每一步在干嘛,出了问题你知道去哪查。等你第三次觉得"又要手动部署好烦"的时候,你已经非常清楚自己在自动化什么了——那时候再上 CI/CD,每一行配置都有明确目的。
收益:没有"我改了代码但不知道为什么没部署上去"这种玄学。
总结
AI 时代,独立开发者的竞争优势不是"谁会用 AI"——大家都在用同一个 AI。
真正的差异在于:你有没有在 AI 帮你生成代码的同时,保留那些让代码可维护的工程纪律。
这些纪律不性感,不酷,不在任何技术趋势里。但它们决定了三个月后你是"继续快速迭代",还是"盯着自己写的代码发呆"。