Composer 应用完,编辑器里改过的文件都没红波浪线,你跑 pnpm build 立刻挂——missing import、type 错位、Prisma client 没更新、ESM/CJS 不匹配。Cursor 的 Apply 只校验它碰过的文件局部正确,不跑全图 typecheck,更不知道 codegen / build step / CI env。结果就是”局部绿、全局红”。
修这类问题的关键不是改具体错误,而是把”完整 build” 纳入 Cursor 协作流程。
常见原因
1. 改了函数签名漏了调用点
Cursor 把 foo(a, b) 改成 foo(a, b, c),但只改了它当时打开的 3 个调用点,仓库其它 7 个调用点报 “Expected 3 arguments, but got 2”。
如何判断:pnpm typecheck 2>&1 | grep "Expected",看错都集中在某一个函数 / type 上。
2. 新建文件没加 import 或 import 路径不对
Composer 创建了 src/utils/parseInvoice.ts,但调用方写的是 from "./utils/parse-invoice"(kebab-case)或 from "@/utils/parseInvoice"(依赖 path alias)。本地 dev server 可能宽容,build 严格。
如何判断:构建错误里出现 “Cannot find module” 或 “Module not found”。
3. Codegen 没重跑
改了 Prisma schema、GraphQL schema、protobuf、OpenAPI 后,对应生成的 client / types 没更新。代码引用的新字段在 generated 文件里根本不存在。
如何判断:错误指向 node_modules/.prisma/、src/generated/、__generated__/ 等目录。
4. ESM / CJS 不匹配
Composer 给你写了 import { foo } from "esm-only-package",但你的项目是 CJS;或者反过来给了 require() 在纯 ESM 项目里。dev 用 ts-node / tsx 可能跑通,build (esbuild / vite / rollup) 会爆。
如何判断:错误带 “ERR_REQUIRE_ESM”、“Cannot use import statement outside a module”、“is not a function”。
5. 引用了 CI 没有的 env / 文件
新代码读 process.env.NEW_TOKEN 或读本地某个 fixture 文件。本地有,CI 容器里没有,build 时报 undefined 或 ENOENT。
如何判断:构建错出现 env name 或文件路径;本地能 build 但 CI 挂。
6. tsconfig 多份(dev vs build)
tsconfig.json 宽松(noEmit, skipLibCheck),tsconfig.build.json 严格(strict, noUnusedLocals)。Cursor 默认按 tsconfig.json 检查,build 走严格那份。
如何判断:ls tsconfig*.json;如果有多份,比较 strict 设置。
动手前先确认
- 确认 build 失败是在本地、CI、还是 production deploy;只在一处挂提示你查 env / 配置差异。
- 复现前先 commit 一次,避免一边改一边丢追踪。
- 记下 Cursor 版本和当前模型;不同模型 import 路径风格不同(有的偏好相对、有的偏好 path alias)。
需要收集的信息
- 完整 build 错误日志(第一条 + 最后一条,中间错通常是级联)。
- Composer 最近一次 turn 的 prompt + diff stat。
tsconfig.json/tsconfig.build.json/package.json里 build script 全文。- 是否有 codegen step;上次成功跑是什么时候。
- 本地 Node 版本 / pnpm 版本 vs CI 上的版本。
最短修复路径
按”先全图扫一遍 → 按错类型对症”。
Step 1:跑完整 typecheck + build
pnpm typecheck # 或 tsc --noEmit
pnpm build
读第一条错误,不是最后一条。AI 引入的错通常是级联,第一条最接近 root cause。
Step 2:签名改动用 Composer 自己扫调用点
I changed the signature of `foo` from (a, b) to (a, b, c).
List EVERY call site in the repo and update each one.
After updating, run `pnpm typecheck` and paste the result.
让 agent 自己跑 typecheck 验证。
Step 3:missing import 让模型修正路径
Build fails with "Cannot find module './utils/parse-invoice'".
The file is actually at src/utils/parseInvoice.ts (camelCase).
Update all import paths to match. Verify with tsc --noEmit.
Step 4:codegen 漂了重跑
pnpm prisma generate
pnpm codegen # GraphQL
pnpm proto # protobuf
把这条加进 .cursorrules:
After any change to *.prisma, *.graphql, or *.proto, you MUST run the matching codegen command before declaring done.
Step 5:ESM/CJS 不匹配按项目实际类型修
看 package.json 的 "type" 字段。"type": "module" 全用 import;缺这个字段或 "type": "commonjs" 全用 require。让 Composer 改成一致的,并 import 时显式加 .js 扩展(ESM 要求)。
Step 6:只在 build / CI 挂的查 env + tsconfig
diff tsconfig.json tsconfig.build.json # 看差异
cat .github/workflows/*.yml | grep -A 3 env
把 build 用的严格 tsconfig 喂给 Composer:
We use tsconfig.build.json (strict mode) for production. Re-check your changes under that config and fix any new errors.
怎么确认已经修好
- 本地
pnpm typecheck && pnpm build全过。 - push 后 CI 全绿,不是只 unit test 绿。
- 在另一台干净机器 clone 后
pnpm install && pnpm build能跑通(验 env / lockfile 没被破坏)。
如果还是没修好
- 把错缩到最小:单文件 import、单条 type 报错。
- 回滚 Composer 那条 commit,确认 build 是否恢复,再逐 hunk 重新 apply。
- 在 forum.cursor.com 搜对应错误文案;附 tsconfig + package.json + 错误日志。
- 抓 View → Output → Cursor 的 agent 日志贴 Bug Reports。
预防建议
- CI 强制:每个 PR 跑完整 typecheck + build + 整套测试,不只是 unit。
- 在
.cursorrules里写 “After any code change, runpnpm buildand report errors before finishing.” - pre-commit hook 至少跑
tsc --noEmiton staged files + 引用方。 - Schema 项目(Prisma / GraphQL / Protobuf)规则里固定写 “schema change must be followed by codegen”。
- 让 Composer 任务以 “I ran the build and it succeeded” 收尾,不是 “I’m done”。