Vibe Coding实战:用AI编程工具重构一个全栈项目

开发者Vibe CodingCursorClaude Code通义灵码项目重构Docker 部署2026-09-26

先设定一个具体的改造对象,后面所有操作都围绕它。项目形态很常见:Express 4 + React,src/routes/index.js 1800 行,路由、SQL、参数校验混在一个文件里;package.json 里有 jest 但没有一个测试文件;.env 三年没人动过;上线方式是 SSH 到服务器上 git pull && pm2 restart。

这次只做三件事,其他一律不碰:

  • 把 1800 行的路由文件按资源拆成目录
  • 让下单、查库存、退款这三条核心路径有能跑的测试
  • 打成镜像部署到一台云服务器,出问题能在三分钟内回到上一版

工具选型:先分清哪类活归哪个工具

AI 编程工具到 2026 年的差异,主要不在补全速度,而在两件事:能不能自己跑命令看结果,以及你能不能看懂它改了什么。

工具形态公开计费档位更适合的活
Cursor独立 IDE(VS Code 分支)Pro 约 20 美元/月,另有更高额度档跨文件改动、Tab 补全、边看 diff 边改
Claude Code终端 CLI含在 Claude Pro(20 美元/月)与 Max 档内,也可换成 API key 按量付费长链路重构、自己跑测试、批量重命名
通义灵码VS Code / JetBrains 插件个人版免费,企业版单独报价国内网络环境、中文注释补全、单测生成
GitHub Copilot编辑器插件个人版 10 美元/月行内补全,跟 GitHub PR 流程配合
价格和额度调整得很勤,动手前去官网 pricing 页确认一遍,别按记忆里的数字买。

实际组合方式:Cursor 开项目,左边看代码,底部终端跑 claude。让 Claude Code 去改文件、跑 npm test、把报错吞掉重试;你在这边盯着 diff 决定收不收。查框架文档的时候,通义灵码在弱网下更省事,Claude Code 则适合把文档页内容直接粘进上下文里问。

需求拆解:把重构切成能被两条命令验证的块

一次会话只解决一个能被命令验证的问题。判断标准很简单:这次改动做完,我能不能用两条命令(一条测试、一条类型检查)判断它对不对。

拆的时候按文件边界切,不要按功能重要性切。功能相关的代码往往耦合,一次动三个模块,测试红了都不知道是哪个引起的。

那 1800 行文件拆成任务卡,大概是这个样子:

  • 抽出 GET /books、GET /books/:id 到 src/routes/books/list.js
  • 抽出订单相关 6 个接口到 src/routes/orders/
  • 把散落在路由里的 SQL 抽到 src/repositories/
  • 调整 src/routes/index.js 的挂载顺序,保证 404 处理还在最后
每个任务的验收标准写死:npm test 全绿,npx tsc --noEmit 无输出。达不到就停,不往下走。

上下文工程:决定 AI 每次能看到什么

上下文给多了,模型被无关代码带偏;给少了,它自己猜,猜错还得你收尾。我把它分三层。

第一层,项目级常驻规则。 Cursor 放在 .cursor/rules/ 下的 .mdc 文件里,带 frontmatter;Claude Code 放在项目根目录的 CLAUDE.md 里,第一次可以用 /init 生成初稿再手改。写规则时只写能被检查的约束,别写「注意代码质量」这种没法验证的话。

---
description: 项目通用约束
alwaysApply: true

  • 运行时 Node 22,包管理用 npm,不要执行任何 yarn / pnpm 命令
  • 数据库连接统一从 src/db/index.js 导出的 pool 取,禁止在路由里 new Client
  • 新增接口必须写 zod schema,放在同目录的 schema.ts
  • 禁止修改 src/routes/legacy/ 下的任何文件
  • 每次改动结束必须跑通:npx tsc --noEmit 和 npm test
**第二层,单次任务的说明。** 包括改哪个文件、不改什么、验收命令是什么。这一段写清楚,能省掉一半来回。

第三层,这一轮对话里 @ 的具体文件。 别指望它自己找,文件名有歧义的时候尤其容易找错。

一次拆路由的提示词,实际长这样:

任务:把 src/routes/index.js 里 /books 相关的 2 个接口拆到 src/routes/books/list.js。

约束:

  • 只允许新建 src/routes/books/list.js,并修改 src/routes/index.js 的挂载部分
  • 不要动 src/db/、src/repositories/ 下的任何文件
  • URL、状态码、响应字段全部保持原样,前端不改
  • 用 express.Router(),在 index.js 里按原来的位置挂载
  • 不要顺手格式化其他行
验收:npx tsc --noEmit 无输出,npm test 全绿。 先告诉我你打算怎么改,等我确认再动手。

最后那句很重要。让它先给方案,你花三十秒看一眼,比它改完 200 行你再回滚便宜得多。

代码审查与测试:AI 说通过不算通过

重构最大的风险是行为悄悄变了。测试是唯一的防线,而存量项目大概率没测试,所以第一步是补特征测试——把现在的行为固定下来,哪怕这个行为看起来不合理。

对 AI 的指令可以这样写:不要改实现代码,先读 src/routes/index.js 里的 POST /orders,写一个测试把它当前的响应结构和状态码固定下来,然后运行 npm test 确认通过。

写完要验一下测试有没有真的在测东西。方法很土但有效:手动把实现里的 res.status(200) 改成 res.status(201),再跑测试。如果还是绿的,这个测试就是摆设。

常见的 AI 测试放水有三种形态:

  • 断言写成 expect(res.body).toBeDefined(),什么都没验证
  • 把被测函数 mock 掉,最后测的是 mock
  • 测试跑不过时,改的是测试而不是实现
第三种最危险,所以规则文件里要写死一句:不要为了让测试通过而修改测试文件,测试失败时把报错原文贴给我。

审查 diff 的时候别点 Accept all。按这个清单逐块看:

看什么具体怎么判断
删除的逻辑有没有把错误处理、边界判断一起删掉
await异步调用有没有漏 await,forEach 里有没有用 async
错误分支try/catch 是不是被改成了静默吞掉
SQLWHERE 条件有没有在搬移过程中变松
导出有没有文件被改了但没被任何地方引用
单次 diff 超过 400 行就拆任务重做,这个量级人眼已经看不住。

整个循环长这样:

flowchart LR A[补特征测试] --> B[AI 出改造方案] B --> C[人工确认范围] C --> D[AI 改一个模块] D --> E{跑测试和类型检查} E -- 失败 --> F[把报错原文贴回去] F --> D E -- 通过 --> G[逐块看 git diff] G --> A

部署到云:让 AI 写文件,让人按发布键

镜像相关的文件(Dockerfile、compose、CI 配置)是 AI 写得又快又好的部分,但生产环境的操作必须由人执行。理由很直接——它看不到你的账单、安全组和证书到期时间。

多阶段 Dockerfile,可以让它按这个骨架生成:

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine WORKDIR /app ENV NODE_ENV=production COPY package*.json ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist USER node EXPOSE 3000 CMD node dist/server.js

生成之后逐条检查四件事:基础镜像有没有 pin 到具体 tag;有没有用非 root 用户跑;.dockerignore 里有没有 .env 和 node_modules;有没有把源码一起复制进运行阶段。

国内服务器上,镜像推到阿里云容器镜像服务(个人版免费),ECS 上用 compose 起:

services:
  api:
    image: registry.cn-hangzhou.aliyuncs.com/your-ns/bookshop:2026-03-01
    env_file: .env
    restart: unless-stopped
    ports:
  • '127.0.0.1:3000:3000'
nginx: image: nginx:1.27-alpine volumes:
  • ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
  • /etc/letsencrypt:/etc/letsencrypt:ro
ports:
  • '80:80'
  • '443:443'
depends_on:
  • api
两个细节值得留意。端口绑 `127.0.0.1` 而不是 `0.0.0.0`,应用容器不直接对公网暴露;镜像 tag 用日期或 commit sha,不用 `latest`——回滚就是把 tag 换回上一个再 `docker compose up -d`,跟重新构建没有任何关系。

数据库迁移别交给 AI 在生产上跑。让它生成 migration 文件,你在预发环境先执行一遍,确认能回滚,再手动上生产。

效率提升与坑点

省时间的做法,本质上都是减少上下文来回搬的次数:

  • 同一类改动批量做。10 个接口的校验逻辑是同一个模式,让 AI 一次改完再统一 review,比改一个聊一次快得多
  • 把验证命令固化到 package.json 的 scripts 里,提示词里直接写 npm run check,不用每次解释要跑什么
  • commit 前挂 pre-commit hook,跑类型检查和 lint,AI 生成的问题在本地就拦掉
  • 一个任务一张卡,做完就 /clear 或开新会话。跨任务的上下文是负资产
踩过的坑集中在这几类:

现象真正的原因处理方式
改了 A 文件,B 功能挂了B 不在上下文里,AI 不知道有依赖把 B 也写进规则或 @ 进去
它说测试通过了,但你没看到输出没真跑,或者跑的是旧结果要求贴出完整命令和原始输出
调用的库函数不存在模型记的是旧版本 API让它先读 node_modules 里的类型定义
会话越聊越糊涂无关内容把上下文挤满了换任务就清空,别硬撑
.env 进了 git生成的配置里硬编码了连接串提交前跑一遍 gitleaks
还有一条容易被忽略:别把生产环境的账号密码、云厂商 AK 放进对话里。需要 AI 写配置的时候用占位符,发布前自己替换。

参考

  • Cursor 官方文档:https://cursor.com/docs
  • Claude Code 官方文档:https://docs.claude.com/en/docs/claude-code/overview
  • 通义灵码官方文档:https://help.aliyun.com/zh/lingma/
  • GitHub Copilot 官方文档:https://docs.github.com/en/copilot
工具版本、计费档位和界面入口都会变,按本文操作前请以各官网当前页面为准。

先做这一件事

打开项目根目录,新建 .cursor/rules/project.mdc(Claude Code 用户写 CLAUDE.md),把三条不能被违反的约束写进去,比如「禁止修改 legacy 目录」「接口响应结构不变」「改完必须过 tsc」。然后挑最小的那个路由文件,让 AI 拆一次。

如果拆完的 diff 你花十分钟还看不明白,说明任务切得太大,退回去再切一刀,别急着合并。

PREMIUM

需要完整版教程?

包含详细步骤、视频演示、提示词模板和可下载资料包。微信支付即时获取。

购买完整版 ¥29.90