1. 项目缘起:为什么我们需要一个叫“impeccable”的东西
第一次看到“impeccable”这个词,是在一个前端群里有人甩了张截图,说“这玩意儿生成的页面比我手写的还干净”。截图里是一个命令行工具跑完之后的输出,终端里滚过几行日志,然后浏览器自动弹出一个本地页面,布局、间距、配色、响应式断点全都处理好了。当时我的第一反应是:又是一个套壳的代码生成器吧。但点进去看了它的工作方式之后,我意识到这东西的思路跟市面上大多数“AI写页面”的工具不太一样。
impeccable这个项目,从名字就能看出来它的野心——无可挑剔。它不是一个独立的编辑器,也不是一个网页版的低代码平台,而是一个命令行工具(CLI),同时配套了一个浏览器扩展(browser extension)。它的核心定位是:让 AI coding agents 在生成前端代码的时候,有一个“审美底线”和“工程规范”的约束层。换句话说,你让 AI 帮你写一个登录页,它不会给你吐出一堆div套div、内联样式满天飞、移动端直接崩掉的垃圾代码。impeccable会在 AI 输出和最终文件之间做一层拦截、校验和修正。
这个项目解决的是一个非常具体的痛点:AI 生成的前端代码,能跑,但不好看,也不好维护。你如果用 Codex CLI、Claude Code 或者其他 AI coding agent 写过前端,肯定遇到过这种情况——功能实现了,但间距是随意的,颜色是拍脑袋的,响应式是碰运气的。你让 AI 改,它改完可能更乱。impeccable的思路是,不跟 AI 硬碰硬,而是在它输出之后,用一套预设的设计系统和代码规范去“打磨”结果。
适合谁来用?三类人。第一类是全栈工程师,后端逻辑很熟,但前端审美和 CSS 工程化经验偏弱,希望 AI 帮忙兜底。第二类是独立开发者,一个人要搞定产品的前后端,没时间细调 UI,但又不想产品看起来像半成品。第三类是前端团队的技术负责人,想给团队里的 AI 辅助开发流程加一道质量关卡,避免 AI 生成的代码直接进主分支。如果你属于这三类中的任何一类,impeccable值得花时间研究一下。
2. 核心机制拆解:它到底是怎么“打磨”AI 生成的前端代码的
2.1 拦截层设计:CLI 与浏览器扩展的分工
impeccable的架构分两块,一块是 CLI,一块是浏览器扩展。这两块不是重复造轮子,而是各管一段。
CLI 负责的是代码生成阶段的约束。当你用codex cli或者类似的工具生成前端代码时,impeccable可以作为中间层介入。它的工作方式是:AI 输出的原始代码先不直接写入文件,而是经过impeccable的解析器,解析器会检查几个维度——HTML 语义化程度、CSS 选择器复杂度、是否有内联样式、响应式断点是否覆盖、颜色和间距是否落在预设的 design token 范围内。检查完之后,它会做两件事:一是自动修正常见问题,比如把margin: 13px这种魔数改成margin: var(--space-3);二是把无法自动修正的问题以警告形式输出到终端,让你决定是手动改还是让 AI 重新生成。
浏览器扩展负责的是运行时验证。CLI 处理完的代码,你在浏览器里打开,扩展会自动扫描页面,检查实际渲染效果和设计系统的偏差。比如某个按钮在移动端被挤出了视口,或者两个相邻卡片的间距不一致,扩展会在页面上用高亮标出来,同时在控制台输出具体的 DOM 节点和计算样式。这个反馈回路很重要,因为很多布局问题在静态代码里看不出来,只有渲染之后才暴露。
注意:CLI 和浏览器扩展需要配合使用才能发挥最大价值。单独用 CLI,你只能保证代码层面的规范;单独用扩展,你只能发现问题但没法自动修正。两个一起用,才能形成“生成-校验-修正-再校验”的闭环。
2.2 设计系统的内置逻辑:为什么是这套 token
impeccable内置了一套设计系统,但它的设计系统不是那种大而全的组件库,而是一套约束规则。核心包括:
- 间距系统:基于 4px 基准的倍数,预设了
--space-1到--space-12,分别对应 4px、8px、12px、16px、24px、32px、48px、64px 等。AI 生成代码时,如果写了padding: 15px,会被自动修正到最近的 token 值,也就是--space-4(16px)。 - 颜色系统:预设了一套中性色和语义色,中性色从
--gray-50到--gray-900,语义色包括--color-primary、--color-danger、--color-success等。AI 如果写了color: #3b82f6,会被映射到--color-primary,前提是这个色值在预设的映射表里。 - 字体系统:预设了字号阶梯和行高比例,避免 AI 生成
font-size: 17px这种不在阶梯上的值。 - 断点系统:预设了
sm、md、lg、xl四个断点,对应 640px、768px、1024px、1280px。AI 生成的媒体查询如果用了 800px 这种非标准断点,会被警告。
这套设计系统的逻辑是:不追求视觉上的惊艳,追求的是视觉上的一致性和可预测性。你让 AI 生成十个页面,每个页面单独看可能都还行,但放在一起就会发现间距不一样、颜色有偏差、字体大小跳来跳去。impeccable的作用就是把这些偏差抹平,让十个页面看起来像一个人写的。
2.3 与 AI coding agents 的协作模式
impeccable跟 AI coding agents 的协作,不是替代关系,而是后处理关系。你可以继续用你习惯的codex cli、trae cli或者任何其他工具来生成代码,impeccable只是在输出链路上加了一道工序。
具体来说,有两种集成方式。第一种是管道模式:AI 生成代码到标准输出,通过管道传给impeccable,处理完再写入文件。这种方式适合脚本化的工作流,比如你在 CI 里跑自动化生成。第二种是监听模式:impeccable监听指定目录的文件变化,一旦 AI 写入了新的前端文件,它自动触发校验和修正。这种方式适合交互式开发,你一边让 AI 改,一边看impeccable的反馈。
我个人的习惯是监听模式,因为管道模式需要你每次手动拼命令,容易忘。监听模式配置一次,后面就不用管了。但监听模式有个坑:如果 AI 在短时间内频繁写入文件,impeccable可能会触发多次校验,导致终端输出刷屏。解决办法是在配置里加一个 debounce 参数,比如debounce: 500,表示文件变化后等 500 毫秒再触发,避免频繁抖动。
3. 从零上手:安装、配置与第一个项目的完整实操
3.1 环境准备与安装步骤
impeccable的安装方式取决于你的运行环境。如果你用的是 Node.js 生态,直接通过 npm 全局安装:
npm install -g impeccable-cli安装完成后,运行impeccable --version确认版本。如果提示命令找不到,检查 npm 的全局 bin 目录是否在 PATH 里。Windows 用户可能会遇到这个问题,解决办法是运行npm config get prefix,然后把输出的路径加到系统环境变量里。
如果你不想全局安装,也可以用npx直接运行:
npx impeccable-cli initinit命令会在当前目录生成一个impeccable.config.json配置文件,同时创建一个.impeccable目录,里面存放设计系统的 token 定义和校验规则。这个目录建议加入版本控制,因为团队协作时,大家需要用同一套规则。
浏览器扩展的安装稍微麻烦一点,因为它目前没有上架官方扩展商店,需要手动加载。在 Chrome 里打开chrome://extensions,开启“开发者模式”,然后选择“加载已解压的扩展程序”,指向impeccable项目里的extension目录。安装成功后,浏览器工具栏会出现一个图标,点击可以开启或关闭当前页面的校验。
提示:浏览器扩展只在开发环境下使用,不要在生产环境的浏览器里长期开启,因为它会注入额外的脚本,可能影响页面性能。
3.2 配置文件详解:每个参数背后的意图
impeccable.config.json是核心配置文件,我挑几个关键参数解释一下。
{ "designSystem": { "spacingBase": 4, "spacingScale": [1, 2, 3, 4, 6, 8, 12, 16], "colorPalette": "default", "fontScale": [12, 14, 16, 18, 24, 32, 48], "breakpoints": { "sm": 640, "md": 768, "lg": 1024, "xl": 1280 } }, "rules": { "noInlineStyles": true, "noMagicNumbers": true, "requireSemanticHtml": true, "maxSelectorDepth": 3 }, "autoFix": { "spacing": true, "colors": true, "typography": true }, "watch": { "enabled": true, "paths": ["src/**/*.html", "src/**/*.css"], "debounce": 500 } }spacingBase是间距的基准值,默认 4px。spacingScale是允许的间距倍数,比如[1, 2, 3, 4, 6, 8, 12, 16]对应的实际像素值是 4、8、12、16、24、32、48、64。如果 AI 写了padding: 20px,impeccable会把它修正到最近的允许值,也就是 16px 或 24px,具体取决于哪个更接近。
rules里的noInlineStyles控制是否禁止内联样式。我建议开启,因为内联样式是 AI 生成代码里最常见的坏味道之一。noMagicNumbers控制是否禁止魔数,也就是那些不在设计系统里的随意数值。maxSelectorDepth限制 CSS 选择器的嵌套深度,超过 3 层的选择器会被警告,因为太深的选择器难以维护。
autoFix控制哪些问题可以自动修正。间距和颜色我建议都开启,因为这两个维度的修正风险最低。字体大小的自动修正要谨慎,因为有时候 AI 用非标准字号是有意为之,比如为了适配某个特殊组件。如果你发现自动修正把不该改的改了,可以把typography设为false,改成只警告不修正。
3.3 第一个实操案例:让 AI 生成一个登录页并打磨
我拿一个真实的例子来演示。我用codex cli生成一个登录页,提示词是“生成一个响应式的登录页面,包含邮箱和密码输入框,一个登录按钮,一个忘记密码链接”。AI 输出的原始 HTML 和 CSS 大概是这样:
<div style="padding: 20px; max-width: 400px; margin: 0 auto;"> <h2 style="font-size: 22px; color: #333; margin-bottom: 18px;">登录</h2> <input type="email" placeholder="邮箱" style="width: 100%; padding: 12px; margin-bottom: 15px; border: 1px solid #ccc; border-radius: 5px;"> <input type="password" placeholder="密码" style="width: 100%; padding: 12px; margin-bottom: 15px; border: 1px solid #ccc; border-radius: 5px;"> <button style="width: 100%; padding: 14px; background-color: #3b82f6; color: white; border: none; border-radius: 5px;">登录</button> <a href="#" style="display: block; text-align: center; margin-top: 12px; color: #3b82f6;">忘记密码?</a> </div>这段代码能跑,但问题很多:全是内联样式,间距是 20px、18px、15px、12px 这种魔数,颜色是硬编码的,没有语义化的表单结构,没有 label 标签,响应式完全没做。
把这段代码保存到src/login.html,然后运行:
impeccable watch终端会输出类似这样的日志:
[impeccable] 检测到文件变化: src/login.html [impeccable] 解析完成,发现 12 个问题 [impeccable] 自动修正: 内联样式 -> 提取到 style 块 [impeccable] 自动修正: padding 20px -> var(--space-5) [impeccable] 自动修正: margin-bottom 18px -> var(--space-4) [impeccable] 自动修正: color #333 -> var(--gray-800) [impeccable] 自动修正: background-color #3b82f6 -> var(--color-primary) [impeccable] 警告: 缺少 label 标签,建议为输入框添加 [impeccable] 警告: 未检测到媒体查询,移动端可能布局异常 [impeccable] 修正完成,输出到 src/login.fixed.html打开login.fixed.html,代码变成了这样:
<style> .login-container { padding: var(--space-5); max-width: 400px; margin: 0 auto; } .login-title { font-size: var(--font-lg); color: var(--gray-800); margin-bottom: var(--space-4); } .login-input { width: 100%; padding: var(--space-3); margin-bottom: var(--space-4); border: 1px solid var(--gray-300); border-radius: var(--radius-sm); } .login-button { width: 100%; padding: var(--space-4); background-color: var(--color-primary); color: white; border: none; border-radius: var(--radius-sm); } .login-link { display: block; text-align: center; margin-top: var(--space-3); color: var(--color-primary); } </style> <div class="login-container"> <h2 class="login-title">登录</h2> <input type="email" class="login-input" placeholder="邮箱"> <input type="password" class="login-input" placeholder="密码"> <button class="login-button">登录</button> <a href="#" class="login-link">忘记密码?</a> </div>内联样式被提取到了 style 块,魔数被替换成了 design token,颜色被映射到了语义变量。但警告还在:缺少 label 和媒体查询。这两个问题需要手动处理,或者让 AI 重新生成一版,在提示词里明确要求“使用语义化表单标签”和“包含移动端媒体查询”。
3.4 浏览器扩展的运行时校验实操
CLI 处理完之后,在浏览器里打开login.fixed.html,然后点击impeccable扩展图标,开启校验。扩展会在页面上做几件事:
第一,检查所有可交互元素的点击区域是否足够大。移动端推荐的最小点击区域是 44x44 像素,如果按钮或链接的实际点击区域小于这个值,扩展会在元素周围画一个红色虚线框,并在控制台输出具体尺寸。
第二,检查文本对比度。如果文字颜色和背景色的对比度低于 WCAG AA 标准(4.5:1),扩展会高亮该文本,并给出建议的修正色值。
第三,检查布局溢出。如果某个元素在特定视口下超出了父容器,扩展会在控制台输出溢出方向和溢出量。
我实测下来,登录页的按钮在移动端视口下点击区域是够的,但“忘记密码”链接的点击区域只有文字本身的大小,大概 80x20 像素,高度不够。扩展给出了警告,我手动给链接加了padding: var(--space-2) 0,把点击区域撑到了 80x36 像素,虽然还没到 44px,但比之前好多了。
实操心得:浏览器扩展的校验结果不要全盘接受,有些警告是“建议性”的,不是“强制性”的。比如对比度检查,如果你的品牌色就是浅色,强行改成深色可能破坏视觉一致性。这时候可以在扩展的设置里把这条规则关掉,或者标记为“已知例外”。
4. 常见问题与排查技巧实录
4.1 自动修正把不该改的改了怎么办
这是最常见的问题。impeccable的自动修正基于规则匹配,但有些场景下,AI 写的“非标准值”是有意为之。比如一个全屏轮播图的高度,AI 写了height: 85vh,这个值不在任何 token 里,但它是合理的。如果impeccable把它修正成了height: var(--space-16),那就完全错了。
解决办法是在配置文件里加一个ignorePatterns数组,用正则表达式匹配那些不应该被自动修正的选择器或属性。比如:
{ "ignorePatterns": [ "height:\\s*\\d+vh", "width:\\s*\\d+vw", "z-index:\\s*\\d+" ] }这样,视口单位的高度、宽度和 z-index 就不会被自动修正了。我建议把z-index也加进去,因为 z-index 的数值往往是业务逻辑决定的,不是设计系统能约束的。
4.2 与现有项目的设计系统冲突怎么处理
如果你的项目已经有一套成熟的设计系统,impeccable的内置 token 可能跟你的不兼容。这时候不要硬套,而是把impeccable的 token 映射到你的系统上。配置文件里有一个tokenMapping字段:
{ "tokenMapping": { "--space-1": "--my-spacing-xs", "--space-2": "--my-spacing-sm", "--space-3": "--my-spacing-md", "--color-primary": "--my-brand-blue" } }这样,impeccable在自动修正时,会输出你项目里已有的 CSS 变量,而不是它自己的。这个映射需要手动配一次,但配好之后,AI 生成的代码就能无缝融入你的项目,不会出现两套变量并存的情况。
4.3 终端输出刷屏怎么治
监听模式下,如果 AI 频繁写入文件,终端会疯狂输出日志。除了前面提到的debounce参数,还可以用logLevel控制输出详细程度:
{ "logLevel": "warn" }logLevel有三个值:info、warn、error。默认是info,会输出所有修正和警告。设为warn后,只输出警告和错误,自动修正的日志就不显示了。设为error后,只输出错误。我平时用warn,既能知道哪里有问题,又不会被修正日志淹没。
4.4 常见问题速查表
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| 安装后命令找不到 | npm 全局 bin 不在 PATH | 运行npm config get prefix检查路径 | 把路径加到系统环境变量 |
| 浏览器扩展不生效 | 扩展未启用或页面未刷新 | 检查扩展图标状态,刷新页面 | 重新加载扩展,确保页面是本地文件或 localhost |
| 自动修正后样式错乱 | 修正规则过于激进 | 查看终端日志,定位被修正的属性 | 在ignorePatterns里排除该属性 |
| 与项目变量冲突 | token 未映射 | 检查生成的 CSS 变量名 | 配置tokenMapping做映射 |
| 终端输出太多 | 日志级别太低 | 查看logLevel配置 | 改为warn或error |
| 校验速度慢 | 监听目录太大 | 检查watch.paths配置 | 缩小监听范围,只监听源码目录 |
4.5 几个我踩过的坑
第一个坑:impeccable默认会校验所有 HTML 文件,包括node_modules里的。我第一次跑的时候,终端刷了几万行日志,全是第三方库的警告。后来在配置里加了ignore: ["node_modules/**", "dist/**"]才清净。
第二个坑:浏览器扩展的对比度检查对渐变背景无效。如果你的按钮背景是渐变色,扩展会取第一个色值来计算对比度,结果可能不准确。这种情况我一般手动检查,或者把渐变改成纯色再校验。
第三个坑:impeccable的自动修正不会处理 CSS 预处理器语法。如果你用的是 Sass 或 Less,它会把$variable当成普通文本,不会做 token 替换。解决办法是先用预处理器编译成纯 CSS,再让impeccable处理。或者,如果你用的是 CSS 变量,那就没问题,因为 CSS 变量在编译前后都是合法的。
5. 进阶玩法:把 impeccable 接入团队工作流
5.1 在 CI 里加一道前端质量门禁
团队协作时,最怕的是 AI 生成的代码直接合并到主分支。你可以在 CI 流程里加一个impeccable检查步骤,比如在 GitLab CI 的.gitlab-ci.yml里:
frontend-quality: stage: test script: - npm install -g impeccable-cli - impeccable check --path src/ --fail-on error only: - merge_requestscheck命令会扫描指定目录,如果发现error级别的问题,就返回非零退出码,CI 会标记为失败。这样,AI 生成的代码如果不符合规范,就过不了 CI,必须手动修正或者重新生成。--fail-on参数可以设为error或warn,我建议设为error,因为warn级别的问题太多,全卡住会影响开发效率。
5.2 自定义规则:让 impeccable 学会你的团队规范
impeccable支持自定义规则。你可以在.impeccable/rules目录下写 JavaScript 文件,每个文件导出一个规则对象。比如,你们团队规定所有按钮必须包含type属性,可以写一个规则:
module.exports = { name: 'button-requires-type', severity: 'error', check: (node) => { if (node.tagName === 'button' && !node.attributes.type) { return { message: '按钮必须包含 type 属性', line: node.line, column: node.column }; } return null; } };这个规则会在解析 HTML 时被调用,如果发现button标签没有type属性,就报错。自定义规则的好处是,你可以把团队的代码规范固化下来,AI 生成的代码自动接受检查,不需要人工 review 每一行。
5.3 与 codex cli 的深度集成技巧
如果你主力用codex cli,可以在它的配置文件里加一个 post-processing 钩子,让每次生成完代码自动跑impeccable。具体做法是在codex的配置里找到hooks字段,加上:
{ "hooks": { "afterGenerate": "impeccable fix --path {{outputPath}}" } }这样,codex cli每次生成完文件,impeccable会自动修正一遍。你拿到的就是已经打磨过的代码,省去了手动跑的步骤。不过要注意,这个钩子会增加生成时间,如果impeccable校验很慢,可能会拖慢整个流程。建议只在生成前端文件时触发,后端文件不需要。
提示:
codex cli的配置格式可能随版本变化,具体字段名以你安装的版本为准。如果找不到hooks字段,可以查一下官方文档,或者用codex cli --help看看有没有相关选项。
6. 我对这个项目的一些个人看法
impeccable这个项目,本质上是在 AI 生成代码和人类审美之间搭了一座桥。它不试图让 AI 变得“更聪明”,而是让 AI 的输出变得“更可控”。这个思路我觉得是对的,因为 AI 的生成能力已经很强了,但它的“品味”和“工程意识”还差得远。与其期待 AI 自己学会写优雅的代码,不如用工具去约束和修正它。
我用了大概两周,最大的感受是:它不能替代前端工程师,但能让前端工程师少擦很多屁股。以前 AI 生成一个页面,我要花半小时调样式、改结构、补响应式。现在impeccable能自动处理掉其中 60% 到 70% 的问题,我只需要处理剩下的 30% 到 40%,而且剩下的问题往往是真正需要人类判断的,比如交互逻辑、视觉层次、品牌一致性。
当然,它也有局限。比如它目前对 CSS-in-JS 的支持还不够好,如果你用的是 styled-components 或者 emotion,impeccable的解析器可能识别不了。另外,它的设计系统偏保守,适合做中后台、工具类产品,如果你要做那种视觉冲击力很强的营销页面,它的自动修正可能会限制你的发挥。这种场景下,我建议把autoFix关掉,只用它的校验功能,把修正权留给自己。
最后分享一个小技巧:如果你不确定某个自动修正该不该接受,可以先用impeccable fix --dry-run跑一遍,看看它会改哪些地方,但不实际写入文件。确认没问题之后,再去掉--dry-run正式执行。这个命令我几乎每次改配置之后都会跑一遍,能避免很多“改完发现改错了”的情况。