AI 改代码后 build 挂了——恢复与诊断

AI 跑完一轮 build 报错。用 diff review、类型检查和定向 revert 修。

你让 Claude Code 跑一个 refactor,半小时后回来发现 npm run build 红了一片:Cannot find name 'XYZ'Module has no exported member 'foo'vite.config.ts:12 Unexpected token。Agent 自信地说”已修复并通过测试”,但 build 不会撒谎。这种”AI 一通改完 build 烂掉”是当下最高频的事故之一,原因多数是它动了不该动的 config 文件、加了不存在的 import、或留了开发期的 mock。这篇给你一套定向 revert 的流程:不用全 reset,10 分钟内能精确找到是哪一处改动炸了 build。

常见原因

按命中率从高到低排序。

1. Agent 改了配置文件(tsconfig / vite.config / next.config)

最常见也最痛。Agent 看到一个类型错就去松 tsconfig.jsonstrict,或者把 vite.config.tsresolve.alias 重写一遍——结果一处类型错变成全局 build 失败。

error TS5023: Unknown compiler option 'allowImportingTsExtensions'.
error during build:
RollupError: "default" is not exported by "src/utils/helpers"

如何判断git diff main -- '*.config.*' tsconfig*.json 看所有 config 文件是否被动过。

2. 加了不存在的 import

Agent 自己虚构了一个 utility 路径(@/utils/superhelper./lib/notFound),TypeScript 编译过不去:

src/components/Form.tsx:5:18 - error TS2307: Cannot find module
  '@/utils/superhelper' or its corresponding type declarations.

如何判断tsc --noEmit 把所有 TS2307 / TS2305 列出来。

3. 残留了 agent 测试期间的 mock

Agent 在调试时塞了 vi.mock('next/router') 或在 next.config.js 里加了 experimental: { mock: true },提交时忘了移除。

Error: <Link> requires an href prop

如何判断:在 diff 里搜 mockstubfixtureTODOXXX 关键字。

4. 删了被其他文件用到的 export

Agent 觉得某个函数没用,删了它。结果其他 5 个文件还在 import:

src/pages/index.tsx:8:10 - error TS2305: Module './lib/auth'
  has no exported member 'verifyToken'.

如何判断:build 失败信息里有 has no exported membercannot find name

5. 包版本不兼容(API breaking)

Agent 升级了某个包的主版本(比如 React 18 → 19、Next.js 14 → 15),但代码里还在用旧 API:

TypeError: ReactDOM.render is not a function

如何判断git diff main -- package.json 看是否有主版本跳跃。

6. ESM / CJS 混用

Agent 在 ESM 项目里写了 require(),或在 CJS 项目里写了顶层 import

SyntaxError: Cannot use import statement outside a module

如何判断:看 package.json"type": "module" 是否设置,对照 import / require 语法。

最短修复路径

按收益排序。Step 1-3 通常能定位 90% 的问题。

Step 1:先 stash,留干净环境对照

不要直接动代码。先存档:

git stash push -m "ai-broken-build-snapshot"   # 存档当前状态
git stash apply                                # 重新应用,不删 stash

这样你随时可以 git stash pop 回到 AI 改完的样子。如果改动已经 commit 了:

git tag broken-build-snapshot                   # 给当前 commit 打个 tag

Step 2:用 git diff 列出所有改过的文件,按风险排序

git diff main --stat

按这个顺序排查(风险从高到低):

优先级文件类型风险
1tsconfig*.json *.config.{js,ts,mjs}一处坏全站
2package.json package-lock.json依赖不兼容
3src/lib/** src/utils/**被多处 import
4src/components/**影响范围有限
5src/pages/** src/app/**单页面失败

Step 3:跑 tsc --noEmit 暴露所有类型错

不要直接 npm run build,build 会在第一个错就停。先:

npx tsc --noEmit | head -50

这一次性把所有类型错列出来,能立刻看出是”一处改动引发的连锁错”还是”多处独立错”。如果都集中在某一个文件相关的 import 上,定位完成。

Step 4:定向 revert 高风险文件

先 revert 配置文件试试 build:

git checkout main -- tsconfig.json vite.config.ts next.config.js
npm run build

如果 build 过了,问题在 config;如果还挂,恢复 config 改动(git stash pop 或重新 apply),再 revert 下一组:

git checkout main -- src/lib/ src/utils/
npm run build

这样二分查找比全 reset 快。每 revert 一组就 build 一次。

Step 5:把根因写回 prompt 让 agent 重做

定位到具体哪几个文件 / 哪几行后,不要自己手改,而是回头给 agent 一个明确的 prompt:

你上次的改动让 build 挂了。具体错误:
[贴完整 tsc --noEmit 输出]

请只做这些事:
1. 不要碰 tsconfig.json / vite.config.ts
2. 修复以上所有类型错,每个错对应一个最小改动
3. 改完先跑 tsc --noEmit,全绿后再说"完成"

明确禁止它再动 config,这样它不会重蹈覆辙。

预防建议

  • 在 CLAUDE.md / AGENTS.md / .cursorrules 里明确禁止改 config 文件,列出具体路径:tsconfig.jsonvite.config.*next.config.*astro.config.*package.json(除装包)
  • pre-commit hook 跑 tsc --noEmitnpm run build,没过不让 commit
  • 让 agent 每次完工前必须自己跑 npm run build 而不仅仅是 npm test
  • 长 refactor 拆成小 commit,每 commit 都能独立 build
  • 配置文件改动单独 review,不和业务代码混在一个 PR
  • git worktree 让 agent 在隔离分支干活,主分支始终保持可 build

相关阅读

标签: #AI 编程 #排查 #排查