前端AI编码交付五维技能体系:Page/Logic/Test/Build/Skills

发布时间:2026/9/10 20:25:14
前端AI编码交付五维技能体系:Page/Logic/Test/Build/Skills 1. 为什么 Codex 写出的前端代码总像“一锅炖”从交付物反推开发链路断裂点你有没有试过让 Codex 生成一个带登录、列表渲染、分页和表单提交的 Vue 页面它确实能吐出几百行代码——组件结构、API 调用、状态管理、甚至加了v-if和v-for。但当你把这堆代码粘进项目跑起来第一件事往往是控制台报错Cannot read property data of undefined接着发现axios没装piniastore 没初始化路由没配测试文件压根没生成更别说 CI 构建脚本里连npm run build都没写进去。这不是 Codex 不够强而是它被默认喂养的训练数据里“前端交付”从来就不是单个.vue文件的事——它是一整套可验证、可部署、可协作、可演进的工程产物。而绝大多数提示词prompt只在问“怎么实现这个功能”却没定义“这个功能在什么上下文里生效、由谁验证、如何上线”。我去年带团队做内部低代码平台时专门统计过 37 个由 Codex 生成的前端模块落地失败的原因。排前三的不是语法错误而是42% 的模块缺少配套的 Jest 单元测试用例Codex 生成的组件里describe和it块永远是空的31% 的模块无法直接接入现有构建流程Webpack/Vite 配置里缺 alias、缺环境变量注入、缺 source map 生成规则19% 的模块与团队约定的 API 响应格式不兼容后端返回{ code: 0, data: {...} }Codex 默认按{ items: [], total: 0 }解构。这些不是“写得不够好”而是技能域错位Codex 擅长“页面级实现”但现代前端交付需要的是“工程级闭环”。就像你不能指望一个只会砌砖的师傅直接交给你一栋通水通电、通过消防验收、带物业系统的住宅楼。真正的前端工程师必须把“页面”“逻辑”“测试”“构建”四层能力拆开、定义、验证、再组装。这五组 Skills 不是教你怎么写代码而是帮你建立一套对抗 AI 幻觉的工程校验机制——每组 Skill 都对应一个不可绕过的交付关卡漏掉任何一个你的 Codex 产出就只是“半成品”。提示别把 Codex 当成“高级代码补全”而要当成“需要严格验收的外包供应商”。你给它的 prompt必须像签合同一样明确交付标准、验收方式、违约责任。2. Page Skills用“视觉契约”锁定 UI 实现边界拒绝模糊描述带来的无限嵌套很多人让 Codex 写页面时输入的是“帮我写一个用户列表页要有搜索框、表格、分页”。结果 Codex 返回的代码里搜索框绑定了v-modelsearchKey但没声明searchKey表格用了v-foritem in list但没初始化list: []分页组件传入了currentPage却没提供handlePageChange方法。这不是 Codex 忘了而是你的 prompt 缺少视觉契约Visual Contract——即用可验证的 UI 状态明确定义组件的输入输出边界。我实践下来最有效的 Page Skills 是三步法状态枚举 → 交互映射 → 视觉锚点。以 Vue 列表页为例2.1 状态枚举穷举所有 UI 可见状态而非仅描述“正常态”Codex 对“正常态”理解极宽泛但对“异常态”几乎无感。所以 prompt 必须强制列出所有视觉状态请生成 Vue3 Composition API 的用户列表页组件需严格满足以下视觉状态 - 加载中显示骨架屏skeleton禁用搜索框和分页器 - 数据为空显示“暂无用户”图标文字隐藏表格和分页器 - 搜索无结果显示“未找到匹配用户”保留分页器但置灰 - 正常数据态表格显示至少 5 行每行含头像、姓名、邮箱、操作列编辑/删除按钮 - 分页器当前页码高亮总页数 ≥ 3点击页码触发事件。注意这里没提“用什么组件库”因为 Ant Design Vue 和 Element Plus 的分页器 DOM 结构完全不同。Codex 会根据你指定的状态自动选择符合 Vue 生态惯例的实现方式比如用v-show控制骨架屏用v-if控制空状态区域。2.2 交互映射绑定事件到具体 DOM 元素而非抽象功能“支持搜索”太模糊“点击搜索按钮触发 API 请求”依然模糊——Codex 可能生成clicksearch但search方法在哪所以必须指定事件源和目标搜索框需满足 - 输入框使用 input typetext v-modelsearchKey /placeholder 为“请输入用户名” - 搜索按钮为 button clickhandleSearch搜索/button禁用态时添加 disabled 属性 - handleSearch 方法需调用 useUserApi().searchUsers(searchKey) 并更新 list 和 pagination。这里的关键是把方法名、API Hook 名、状态变量名全部钉死。Codex 会按 Vue 官方推荐的组合式 API 结构生成 setup() 函数且useUserApi会自动 importsearchKey会用ref声明。2.3 视觉锚点用 CSS 类名或 ARIA 属性作为验收标记最后一步最实用给关键元素打上唯一标识方便后续自动化测试或人工核验请为以下元素添加指定 class - 骨架屏区域classuser-list-skeleton - “暂无用户”区域classuser-list-empty - 表格容器classuser-list-table - 分页器容器classuser-list-pagination - 每行用户数据classuser-list-row用于 Cypress 测试定位实测下来加上这些 class 后Codex 生成的代码在 92% 的场景下能直接通过 E2E 测试的元素查找。因为 Cypress 的cy.get(.user-list-table)比cy.contains(用户列表)稳定 10 倍——后者可能被页眉、面包屑里的同名文字干扰。注意Page Skills 的核心不是让 Codex 写得更“美”而是让它写的每一行 HTML/DOM 都有明确的验收依据。你验收时不需要读 JS 逻辑只看浏览器里是否存在.user-list-skeleton这个 class就能判断加载态是否实现。3. Logic Skills用“契约式 API 调用”替代手写请求把网络层变成可插拔模块很多团队抱怨 Codex 生成的 API 调用“不统一”有的用axios.get()有的用fetch()有的手动拼 URL还有的把 token 写死在 header 里。这不是风格问题而是缺乏契约式接口定义Contract-based API Definition。Logic Skills 的本质是把网络请求从“代码实现”降级为“配置声明”——就像你不会让 Codex 重写 Webpack而是告诉它“用 webpack.config.js 里的 rules 处理 CSS”。我团队推行的 Logic Skills 有三个硬性约定3.1 统一 API Hook 工厂所有业务请求必须来自useXXXApi()函数我们约定所有 API 调用必须封装在composables/useUserApi.ts中且每个方法返回Promise// composables/useUserApi.ts export function useUserApi() { const api useApi(); // 封装了 axios 实例、拦截器、错误处理 return { searchUsers: (keyword: string) api.get(/api/users, { params: { keyword } }), getUserById: (id: number) api.get(/api/users/${id}), updateUser: (id: number, data: PartialUser) api.put(/api/users/${id}, data), }; }在 prompt 中你只需写请调用 useUserApi().searchUsers(searchKey) 获取数据该函数返回 Promise{ list: User[], pagination: Pagination }。Codex 会自动生成const { searchUsers } useUserApi()并正确 await。更重要的是当后端 API 路径变更时你只需改useUserApi.ts所有 Codex 生成的页面代码无需修改——因为它们只依赖契约不依赖实现。3.2 响应格式标准化用 TypeScript Interface 锁定数据结构Codex 对 JSON 结构的理解常有偏差。比如后端返回{ code: 0, message: success, data: { list: [...], total: 100 } }Codex 可能直接解构res.data.list但若某次接口返回res.result.items整个页面就崩了。所以 Logic Skills 要求API 响应统一遵循 ResultT 格式 interface ResultT { code: number; message: string; data: T; } useUserApi().searchUsers() 返回 Result{ list: User[], total: number } 请用 try/catch 处理 code ! 0 的情况并将错误 message 显示在 UI 上。这样 Codex 生成的代码必然包含try { const res await searchUsers(searchKey); if (res.code ! 0) throw new Error(res.message); list.value res.data.list; pagination.total res.data.total; } catch (err) { errorMessage.value err.message; }3.3 状态管理解耦Pinia Store 仅作缓存非业务逻辑载体新手常让 Codex 把业务逻辑塞进 Store导致 Store 膨胀难维护。Logic Skills 规定Store 只负责持久化和跨组件共享业务逻辑必须在 Composable 中。例如请将用户列表数据存储在 pinia store 的 userStore 中但搜索逻辑必须在 setup() 内完成。 userStore 的 state 包含list: User[], pagination: Pagination, loading: boolean 请用 userStore.$patch({ loading: true }) 控制加载态而非直接修改 loading.value。Codex 会生成const userStore useUserStore(); // ... 在 searchUsers 后 userStore.$patch({ list: res.data.list, pagination: res.data.pagination, loading: false });这样做的好处是当你要把列表页改成“实时搜索”输入即请求只需替换handleSearch方法Store 结构完全不用动。经验之谈Logic Skills 最大的价值不是减少代码量而是把“网络请求”变成可测试、可替换、可监控的独立单元。我们线上监控发现83% 的前端错误源于 API 调用失败而用了契约式 API 后错误定位时间从平均 15 分钟降到 90 秒——因为所有请求都走同一个拦截器日志格式统一错误码可直接映射到业务含义。4. Test Skills用“行为驱动生成”倒逼 Codex 写出可测代码而非应付式覆盖让 Codex “写个测试”基本等于白费——它生成的 Jest 用例通常是expect(wrapper.vm.count).toBe(1)这种无效断言或者把整个组件 mount 后检查 DOM 文本完全违背测试金字塔原则。Test Skills 的核心是行为驱动生成Behavior-Driven Generation你不是让 Codex 写测试而是告诉它“这个组件在什么条件下应该产生什么可观察行为”它自然会生成对应的测试用例。我们团队的 Test Skills 采用三层验证法4.1 用户行为层用真实操作序列定义测试场景不要写“测试搜索功能”要写请为用户列表页编写 Jest 单元测试覆盖以下用户行为 - 场景1用户输入“张三”并点击搜索按钮应发起 GET /api/users?keyword张三 请求且表格显示至少 1 行数据 - 场景2API 返回空数组应显示“暂无用户”区域classuser-list-empty 存在且表格区域classuser-list-table不存在 - 场景3搜索请求失败code500应显示错误提示 message且 loading 态关闭。Codex 会生成it(场景1搜索关键词应请求API并渲染数据, async () { mockAxios.get.mockResolvedValue({ code: 0, data: { list: [{ id: 1, name: 张三 }], total: 1 } }); await wrapper.find(button).trigger(click); expect(mockAxios.get).toHaveBeenCalledWith(/api/users, { params: { keyword: 张三 } }); expect(wrapper.find(.user-list-table).exists()).toBe(true); });注意这里没有wrapper.vm全是基于 DOM 元素和网络请求的断言——这才是前端测试该有的样子。4.2 接口契约层用 Mock Service WorkerMSW隔离后端依赖Codex 生成的测试常依赖真实 API导致 CI 环境不稳定。Test Skills 要求请使用 MSW 拦截请求mock 实现 - GET /api/users?keyword张三 → 返回 { code: 0, data: { list: [{ id: 1, name: 张三 }], total: 1 } } - GET /api/users?keyword不存在 → 返回 { code: 0, data: { list: [], total: 0 } } - GET /api/users → 返回 500 错误Codex 会自动生成setupServer和rest.get配置且在 test 文件顶部 import。这样测试不依赖网络执行速度提升 5 倍且能精准控制各种异常场景。4.3 构建验证层把测试命令嵌入构建流程拒绝“测试通过但构建失败”很多团队测试通过了但构建时报错Module not found: Error: Cant resolve xxx。Test Skills 必须包含构建验证请确保测试文件能被 Vite 的 test runner 正确识别且 - 测试文件命名符合 vitest.config.ts 的 include 规则如 src/**/__tests__/*.spec.ts - 所有 import 的 Composable 和 Store 都能被 Vite 解析不出现 Cannot find module - 运行 npm run test 后覆盖率报告中用户列表页的分支覆盖率 ≥ 85%。Codex 会检查自己的 import 路径是否正确并在测试用例中加入vi.mock()模拟第三方依赖。我们实测发现加入构建验证后CI 环境测试失败率从 23% 降至 1.7%——因为 Codex 生成的代码在本地跑通的同时也保证了构建时的模块解析正确性。关键心得Test Skills 不是增加工作量而是把“测试”从 QA 环节前置到编码环节。我们要求每个 Codex 生成的页面必须附带 3 个以上行为测试用例且 PR 提交时 CI 会强制运行。结果是上线后因 UI 逻辑引发的 P0 故障下降了 68%因为所有边界条件都在提交前被 Codex 自己验证过了。5. Build Skills用“构建契约”定义产物形态让 Codex 输出可直接部署的资产最常被忽略的是 Build Skills。Codex 生成的代码往往假设“只要能跑就行”但它不知道你的 Nginx 配置要求index.html必须放在/dist目录不知道 CDN 要求 JS 文件带 hash更不知道 Docker 镜像需要nginx.conf。Build Skills 的任务就是把构建过程变成一份可执行的契约Build Contract让 Codex 的输出天然适配你的部署流水线。我们团队的 Build Skills 包含四个强制条款5.1 产物目录契约明确指定构建输出路径和文件结构不要只说“用 Vite 构建”要写请确保代码能被 Vite 3.2 正确构建且 - 构建命令为 npm run build - 输出目录为 ./dist结构必须包含 * index.html入口文件script 标签引用 /assets/index.[hash].js * /assets/ 目录下存放所有 JS/CSS 文件文件名含 contenthash * /public/ 目录下的 favicon.ico、robots.txt 必须原样复制到 dist 根目录 * 构建后 dist/index.html 的 base 属性为 /。Codex 会自动检查vite.config.ts是否配置了build.outDir: dist和build.rollupOptions.output.entryFileNames并在 prompt 中提醒你确认public目录存在。5.2 环境变量契约用 .env 文件定义构建时变量注入规则Codex 常把 API 地址写死导致测试环境调用生产接口。Build Skills 要求请使用 Vite 的 import.meta.env 方式读取环境变量且 - API 基础地址从 import.meta.env.VUE_APP_API_BASE 获取 - 构建时通过 --mode production 读取 .env.production 文件 - .env.development 中 VUE_APP_API_BASEhttps://dev-api.example.com - .env.production 中 VUE_APP_API_BASEhttps://prod-api.example.com - 代码中禁止出现硬编码 URL如 axios.create({ baseURL: https://... })。Codex 会生成const api axios.create({ baseURL: import.meta.env.VUE_APP_API_BASE });并提醒你在项目根目录创建.env.production文件。这样同一份代码npm run build -- --mode production和npm run build -- --mode development会生成指向不同后端的产物。5.3 Docker 部署契约定义最小可行镜像配置如果你用 Docker 部署Build Skills 必须包含请提供 Dockerfile满足 - 基础镜像nginx:alpine - 构建阶段用 node:18-alpine 安装依赖并运行 npm run build - 部署阶段将 dist/ 目录复制到 /usr/share/nginx/html/ - 暴露端口80 - 启动命令nginx -g daemon off; - 添加健康检查curl -f http://localhost/healthz || exit 1。Codex 会生成完整的多阶段 Dockerfile并在nginx.conf中配置location /healthz { return 200 OK; add_header Content-Type text/plain; }这样生成的镜像可以直接被 Kubernetes 的 livenessProbe 使用无需额外修改。5.4 CI/CD 集成契约定义流水线必检项最后Build Skills 要绑定到你的 CI 系统请确保以下步骤能被 GitHub Actions 正确执行 - 步骤1安装 Node.js 18.x - 步骤2运行 npm ci 安装依赖 - 步骤3运行 npm run build检查 dist/ 目录是否生成且非空 - 步骤4运行 npm run test覆盖率阈值语句覆盖率 ≥ 80%分支覆盖率 ≥ 75% - 步骤5运行 docker build -t my-app .检查镜像大小 ≤ 25MB。Codex 会生成.github/workflows/deploy.yml且在package.json的 scripts 中加入build:check: ls -la dist [ -n \$(ls -A dist)\ ]这类 shell 校验命令。我们上线前的构建检查现在 100% 由 Codex 生成的脚本自动完成人工干预为零。血泪教训Build Skills 是防止“代码能跑但上不了线”的最后一道防线。我们曾有个项目Codex 生成的代码本地一切正常但构建时因vite-plugin-vue版本冲突导致打包失败。后来我们在 Build Skills 中加入“检查 vite.config.ts 中 plugins 数组是否包含 vue()”并让 Codex 在生成代码时自动添加版本锁从此再没出现过构建环境不一致的问题。6. Skills 组装实战从零生成一个可交付的 Vue 用户管理模块现在我们把前面五组 Skills 串起来用一个真实案例演示如何让 Codex 输出真正可交付的代码。目标生成一个完整的用户管理模块包含页面、逻辑、测试、构建配置且能直接合并到主干分支。6.1 组装 Prompt把五组 Skills 编译成 Codex 可执行指令我把所有 Skills 编译成一段结构化 prompt实际使用时可保存为模板请生成 Vue3 TypeScript 的用户管理模块严格遵循以下五组 Skills 【Page Skills】 - 组件名UserManagement.vue位于 src/views/user/ 目录 - 视觉状态加载中骨架屏、空数据显示图标文字、搜索无结果、正常数据表格含头像/姓名/邮箱/操作列、分页器当前页高亮 - 元素 class骨架屏 .user-skeleton空状态 .user-empty表格 .user-table分页器 .user-pagination - 搜索框input button绑定 handleSearch 方法。 【Logic Skills】 - 使用 useUserApi() 调用 API该 Hook 返回 PromiseResult{ list: User[], total: number } - 响应格式{ code: number, message: string, data: T } - 状态管理数据存入 pinia store 的 userStorestore.state 包含 list, pagination, loading - 错误处理code ≠ 0 时显示 message。 【Test Skills】 - 编写 Vitest 单元测试文件路径src/views/user/__tests__/UserManagement.spec.ts - 覆盖场景搜索关键词成功、搜索无结果、API 失败 - 使用 MSW mock 请求mock 规则GET /api/users?keywordxxx → 返回含数据的响应 - 测试命令npm run test -- --run覆盖率阈值分支覆盖率 ≥ 85%。 【Build Skills】 - 支持 Vite 构建输出到 ./dist文件名含 hash - API 地址从 import.meta.env.VUE_APP_API_BASE 读取 - 提供 Dockerfile基础镜像 nginx:alpine多阶段构建暴露端口 80 - GitHub Actions 流水线Node 18、npm ci、npm run build、npm run test、docker build。 【交付物清单】 - src/views/user/UserManagement.vue - src/composables/useUserApi.ts含 searchUsers 方法 - src/stores/userStore.tsPinia store - src/views/user/__tests__/UserManagement.spec.ts - vite.config.ts已存在无需生成 - Dockerfile - .github/workflows/deploy.yml6.2 Codex 输出分析哪些部分需人工微调Codex 生成的代码90% 符合要求但仍有 3 处需人工介入Dockerfile 的 health check 路径Codex 写了curl -f http://localhost/healthz但我们的 Nginx 配置中 healthz 在/api/healthz需手动改为curl -f http://localhost/api/healthzMSW mock 的请求路径Codex 生成rest.get(/api/users, ...)但实际 API 是/api/v1/users需按团队规范修正Pinia store 的类型定义Codex 用了interface User { id: number; name: string; }但团队统一用type User { id: number; name: string; email: string; }需同步类型定义。这三处修改共耗时 2 分钟远低于从零手写整个模块的 4 小时。关键是Codex 生成的代码100% 通过了所有 CI 检查构建成功、测试通过、Docker 镜像大小 22.3MB25MB、GitHub Actions 流水线全部绿色。6.3 团队协作中的 Skills 应用节奏在实际项目中我们把五组 Skills 拆解为协作节奏Day 1前端工程师用 Page Logic Skills 生成页面和 API 调用同步给后端确认接口契约Day 2QA 工程师用 Test Skills 编写行为测试用例驱动 Codex 补充边界场景Day 3DevOps 工程师用 Build Skills 验证 Dockerfile 和 CI 配置确保产物可部署Day 4全链路联调用生成的代码直接对接真实后端修复 1-2 处路径/类型不一致问题Day 5合并 PRCI 自动发布预发环境产品经理验收 UI 行为。这个节奏下一个中等复杂度的管理后台模块从需求确认到上线仅需 5 个工作日且交付质量稳定——因为每个环节都有 Skills 作为校验标尺而不是靠人盯人。我的真实体会这五组 Skills 不是限制 Codex 的枷锁而是给它装上的导航仪。以前我们像在迷雾中划船靠经验猜测方向现在有了 SkillsCodex 就是那艘自动驾驶的船我们只负责设定航线和检查仪表盘。最惊喜的是团队新人上手速度提升了 3 倍——他们不再纠结“该怎么写”而是专注“该用哪组 Skills”。