Codex 写的前端代码能运行,为什么还是一眼不像这个项目?

发布时间:2026/8/6 19:55:44
Codex 写的前端代码能运行,为什么还是一眼不像这个项目? 前两篇解决了 Codex 接手陌生前端项目的第一步先确认项目边界、规则、执行方式和启动链再沿目录、配置和入口文件建立最小项目地图。地图建立以后文件通常已经找对了但新的问题很快会出现Codex 写出的代码可以运行命名也不算离谱为什么放进项目里还是一眼能看出“不是原来那套写法”很多人把这种感觉概括成“代码风格不一致”然后在提示里加一句请遵守现有项目代码风格。这句话方向没错约束力却很弱。因为前端项目的代码风格远不止缩进、引号和变量命名。真正让代码显得属于同一个项目的往往是那些不容易被格式化工具发现的工程选择状态放在哪里、请求怎样进入页面、组件暴露什么接口、失败后保留什么、关闭时清理什么以及公共能力应该复用到什么程度。所以我现在不会笼统要求 Codex “模仿风格”。我会先把风格拆成 5 个层次再判断每一层的可信证据是什么。第一层表面格式——最容易统一也最不值得靠文字反复强调第一层是最直观的内容缩进引号分号换行导入排序属性排列CSS 或 SCSS 的基本格式。这部分当然属于代码风格但它通常不该占据提示词和项目规则的大部分空间。如果项目已经有格式化、Lint 或编辑器配置就应该优先复用这些机械检查。让 Codex 在提示里记住几十条格式要求不如让它修改后运行项目已有检查再审查自动修正是否扩大了差异。我更关心的是两个边界不要为了统一格式扩大修改范围一个局部功能修改不应该顺手格式化整个文件更不应该把无关目录全部重排。格式正确不代表差异合理。不要把工具已经能判断的事情写成大段自然语言如果项目检查已经明确引号、分号和导入顺序规则只需要说明运行哪个现有检查、是否允许自动修复以及修复范围不能超出当前任务。表面格式是最容易发现的不一致却很少是“外来感”的主要来源。第二层结构风格——代码应该放在哪里由哪一层负责结构风格决定一个功能怎样被拆进项目。例如新增一个列表筛选条件代码可能放在页面组件内部独立组合函数状态模块请求参数转换层公共查询组件路由查询参数同步逻辑。这些实现都可能符合框架语法但项目通常已经形成自己的职责边界。Codex 如果只读目标页面很容易采用一种通用写法页面里增加状态、拼参数、发请求、处理 Loading。单文件看起来完整放进一个已经把请求和状态统一封装的项目里就会显得非常突兀。我判断结构风格时会问同类能力通常落在哪一层页面容器和业务组件分别承担什么公共封装的使用边界是什么哪些逻辑允许留在页面哪些必须下沉当前任务是否真的值得增加新的抽象最后一个问题很重要。遵守结构风格不等于看到项目有组合函数就把所有局部逻辑都抽出去也不等于存在公共组件就强行把当前差异塞进公共组件。项目风格包含复用习惯也包含“不为了一个调用点提前抽象”的克制。第三层状态风格——同一个值由谁拥有什么时候变化前端代码最容易出现“能跑但不像”的地方通常是状态归属。一个项目可能习惯页面内管理一次性查询条件状态模块保存跨页面共享数据弹窗打开时重新构建表单模型通过计算属性派生展示状态请求状态由统一封装维护路由参数作为筛选条件的唯一来源。如果 Codex 没有识别这些约定就容易创造第二份状态。例如列表页面已有queryState作为查询条件来源AI 为了方便给筛选组件再建一个localForm查询时手动同步。正常点击可能没有问题但重置、浏览器返回、路由恢复和异步刷新时两份状态就可能分叉。这不是命名问题而是项目对“谁拥有状态”的判断被改变了。我会重点检查当前值的唯一可信来源子组件是否保存了不该长期拥有的副本派生值是否被重复存储异步状态是否有明确开始、结束和清理页面离开或弹窗关闭后状态按什么规则恢复多个页面是否依赖同一份状态。状态风格一旦偏离代码即使写得很整齐后续维护者仍然要在不同模型之间来回切换。第四层契约风格——组件和接口怎样表达边界前端项目中的契约主要包括PropsEmits插槽暴露方法类型定义接口请求与响应状态模块对外方法事件和回调约定。同样一个“编辑弹窗”可以有完全不同的契约方案 A父页面传完整对象弹窗只负责编辑 方案 B父页面只传 ID弹窗自行请求详情 方案 C父页面控制数据弹窗只暴露表单能力 方案 D通过公共弹窗框架注入上下文并返回结果四种方案没有脱离业务上下文的唯一答案。但在一个已有项目里随意换契约会扩大影响范围。Codex 容易根据当前文件的便利选择 API缺数据就多加一个 Prop需要关闭就多加一个 Emit需要父级调用就暴露一个方法。每一步都说得通最后却形成项目里独有的一套交互方式。我会要求它先回答同类组件通常由谁取数据父子组件怎样分配状态和副作用事件名称和负载有没有稳定模式可选、必填和默认值怎样表达原有调用方是否依赖未写明的行为新契约是否迫使无关调用方一起修改。契约风格的核心不是 API 长得像而是责任边界与项目一致。第五层行为风格——异常、反馈和生命周期怎样收尾最容易被忽略的风格是项目怎样处理“事情没有顺利发生”。例如请求失败以后保留旧列表还是清空保留用户输入还是恢复初始值使用全局提示、局部错误还是表单项错误按钮何时恢复弹窗是否继续打开是否允许用户重试较早请求返回时是否能覆盖新状态。这些选择不仅影响体验也形成了项目的行为一致性。如果一个项目的编辑弹窗都在保存失败后保留输入Codex 新写的弹窗却在finally中重置并关闭它的代码可能没有语法问题用户体验却完全变了。生命周期也是如此打开时初始化还是首次挂载时初始化关闭时清理还是下一次打开时覆盖页面缓存后怎样恢复组件卸载后怎样处理未完成请求连续切换对象时怎样防止旧结果覆盖。这些行为无法靠格式化工具统一只能从需求、稳定参考和页面验证中确认。为什么让 Codex “参考附近代码”仍然不够邻近代码是重要线索但不是天然标准。我遇到过的典型风险可以归为四类。附近代码可能是历史实现它离目标文件最近只能说明目录接近不能说明当前推荐。新模块和旧模块可能恰好放在同一目录中。附近代码可能是特例某个页面因为权限、性能或兼容要求采用特殊结构。脱离原因复制只会把例外扩散成新模式。附近代码可能本身正在偿还技术债真实项目不可能每个文件都一致。Codex 如果看到两种写法可能选择实现更完整或更容易理解的一种却不知道团队正在逐步淘汰哪一种。附近代码可能只覆盖正常路径页面结构看起来相似异常、关闭重开和状态恢复规则却不同。只模仿模板部分最容易漏掉行为差异。所以我会给参考实现设置优先级而不是让 AI 自己从搜索结果中投票。我使用的参考优先级从高到低我通常按下面顺序判断当前任务的明确需求和验收标准适用于当前目录的项目硬规则当前模块中仍在维护的同类实现直接调用关系上的现有契约项目其他模块的稳定模式框架或工具的通用做法。这里有一个关键点项目代码并不自动高于明确需求。如果需求就是要修正一种旧行为不能为了“保持风格”继续复制错误。相反如果需求没有要求改变公共模式Codex 也不应因为通用方案更漂亮而替换项目既有做法。我会要求它在使用参考时说明参考文件在哪里它与当前任务相同的是什么不同的是什么为什么当前选择可以迁移哪些部分不能照搬。这比一句“已参考现有代码风格”更容易审查。风格不一致时不要用多数票决定陌生项目中发现多种写法是正常的。例如三个表单分别采用直接替换响应式对象逐字段恢复初始值调用公共重置方法。文件数量最多的写法不一定是标准。它可能只是旧代码更多。我会按四个问题处理冲突哪一种有明确规则支持如果项目说明或目录规则已经明确就不再靠猜测。哪一种仍在近期维护的模块中使用这里不是简单按日期判断而是看当前目标模块是否与它属于同一代架构和同一套依赖。哪一种能与现有调用契约兼容即使某种写法更理想如果会迫使计划外调用方改变也不适合作为当前小任务的默认选择。当前任务是否有充分理由偏离偏离可以发生但需要写清原因、影响和验证方式不能悄悄把新风格引进项目。如果四个问题仍然无法得出结论我会让 Codex 把冲突列为待确认项而不是替团队发明标准。我会让 Codex 先交一张“风格证据表”进入修改前可以先用下面的表检查它到底理解了什么# 当前任务风格证据表 ​ | 风格层次 | 当前项目做法 | 参考位置 | 适用理由 | 当前任务是否沿用 | | --- | --- | --- | --- | --- | | 格式 | 由哪些项目检查控制 | 配置或脚本 | 当前目录受其覆盖 | 是 / 否 | | 结构 | 页面、组件、状态和请求怎样分工 | 同类稳定模块 | 职责相同或相近 | 是 / 调整 | | 状态 | 唯一来源、派生和清理方式 | 状态或页面实现 | 生命周期一致 | 是 / 调整 | | 契约 | Props、Emits、接口与类型模式 | 组件及调用方 | 调用关系一致 | 是 / 调整 | | 行为 | Loading、失败、重试和关闭规则 | 页面路径或测试 | 用户场景一致 | 是 / 调整 | ​ ## 冲突与例外 - 发现的多种写法 - 不能直接照搬的参考 - 需要人确认的选择这张表不要求每次都写得很长。局部低风险任务可以只覆盖真正受影响的两三层。它的作用是让“风格”从感觉变成证据我可以看到 Codex 依据哪个文件作判断也能及时发现它把特例当成了规范。修改完成后我从三个方向检查风格看差异是否引入新的模式新增了新的工具函数、状态副本、错误处理方式或组件接口吗如果有项目里为什么需要第四种写法看已有能力是否被绕开项目已有请求、弹窗、反馈、权限和状态封装当前实现是否重新造了一套局部版本看行为是否与参考真正一致不仅看模板和命名还要走正常、失败、关闭重开和连续操作路径。结构相似不代表生命周期相同。我尤其会检查“无关优化”。Codex 为了让代码更统一可能顺手重命名、整理导入、抽取函数或调整样式。即使改动本身合理只要与当前目标没有直接关系就会增加审查成本和回归风险。“遵守风格”不能覆盖的三个问题第一项目里没有答案的业务选择不能靠风格推断。第二已有代码中的缺陷不能因为到处存在就继续复制。第三公共架构是否演进不能由一次局部任务顺手决定。风格约束的作用是减少不必要的自由度不是取消工程判断。写在最后Codex 写出的前端代码有没有“项目感”不能只看格式和命名。我会从 5 个层次判断表面格式是否由项目工具统一代码是否放在正确的职责层状态是否沿用项目的归属和生命周期组件与接口契约是否保持一致异常、反馈和清理行为是否符合现有用户路径。真正有效的做法不是让 Codex 泛泛“模仿附近代码”而是给参考设置优先级要求每个关键选择带来源遇到冲突就显式暂停。下一篇我会把这些判断进一步压缩成项目规则哪些内容值得写进AGENTS.md怎样写才能减少 Codex 的无关修改哪些格式问题应该交给自动检查以及规则怎样按仓库和目录范围分层。本系列持续更新。接下来会从“识别现有风格”进入“把稳定约束写成可执行规则”再沿调用链检查规则是否真的控制住了修改范围。每日好工具推荐在这里推荐一款超好用的图片压缩工具——“图压”在线图片压缩免费压缩 JPG、PNG、WebP - 图压工具。同事安利给我的用过后真的觉得太香了支持批量压缩、调整压缩百分比最关键的是它是离线程序下载到本地就能反复用。我平时做自媒体和写前端时经常用到再也不用去网上找在线压缩工具了。它也带在线压缩功能很方便。