你让 AI 生成了一批页面,本地跑起来发现有的地方样式不对、有的筛选按钮点了没反应。逐个看代码,你会发现问题不是逻辑——是成片的拼写错误。
现象
一批页面出现两类症状:
- 样式不生效:元素该有的圆角、背景、布局都没出来;
- 筛选完全没反应:点了按钮,列表没有任何变化。
看起来像两个不相干的问题,但排查下来根因是同一个。打开代码能看到一片低级错误:
.surface-watm { } /* 应为 surface-warm */
flex-direction: tow; /* 应为 row */
theme = 'datk'; /* 应为 dark */
theme = 'watm'; /* 应为 warm */
还有把保留字当变量名用,导致引用未定义的情况。"筛选没反应"往往就是最后一类——值拼错了,CSS 里没有匹配的选择器,样式没应用,看起来就像"点了没反应"。
根因
这些代码是批量生成的。
生成模型在产出大量重复结构的代码时,对"高度相似但不同的字符串"的区分能力不稳定——warm / watm、dark / datk、row / tow,这些字符串在语义上很像,模型容易写错。
而这类错误有个共同特征:不会导致语法错误、不会抛异常,只会静默失效。 CSS 里写个不存在的类名,浏览器不会报错,只是这条规则匹配不到任何元素。JS 里给变量赋个拼错的值,如果没有类型检查也不会报错。
雪上加霜的是:这些错误是成片出现的。因为同一个变量名 / 类名会在一个文件里出现几十次,一旦生成时错了,就错一片。而生成的代码量大、重复度高,人工逐行看很难发现这种"看起来差不多"的拼写问题——眼睛会自动把 watm 读成 warm。
解决
第一步,逐个修正。 用全局替换把拼错的名字统一改掉,注意要确认替换后的名字和样式表里的选择器完全一致。
第二步,建立"主题值 ↔ 选择器"的对应关系检查。 把主题值的所有可能取值(dark / light / warm / ...)列出来,grep 一遍代码里出现过的主题字符串,看看有没有不在这个列表里的:
# 把代码里所有 theme 赋值抓出来,人工比对
grep -rn "theme\s*=" src/ | sort -u
第三步,也是关键的一步——代码生成后必须有一轮 lint / 复核。
npx eslint . --ext .js,.ts,.vue
npx stylelint "**/*.css"
npx tsc --noEmit
ESLint 能抓出"引用未定义的变量"和"把保留字当变量名"这两类;TypeScript 的类型检查能抓出一部分赋值类型错误;stylelint 能抓到一部分属性值错误。虽然 flex-direction: tow 这类未必能全覆盖,但至少变量名和引用问题能拦住。
第四步,写一个小的校验脚本,检查模板里出现的所有 class 名是否都在样式表里存在:
# 提取模板里的 class,逐个查是否在 css 里定义
grep -rho 'class="[^"]*"' src/ | tr ' ' '\n' | sort -u > used.txt
grep -rho '^\s*\.[a-z-]*' src/**/*.css | tr -d ' .' | sort -u > defined.txt
comm -23 used.txt defined.txt # 只在 used 里、不在 defined 里的
延伸与预防
核心原则:机器生成的代码必须过一次机器校验。
具体做法:
- 把 lint 挂到提交前钩子(pre-commit),过不了不让提交;
- 对生成结果先做一遍"关键字符串一致性检查"(主题值、枚举值、路由名这类),用脚本比对而不是肉眼看;
- 如果一种错误已经出现了,同类位置大概率还有——要全量扫一遍,而不是只修报错的那处。
最后一条尤其重要:看到一个 watm,就直接把所有 watm / datk 之类搜一遍。拼写错误从来不是孤立出现的。