1. 项目概述与核心定位
1.1 这个项目到底在解决什么问题
第一次看到 "impeccable" 这个词,很多人会以为是某个新出的前端框架或者代码检查工具。实际上,它瞄准的是一个更底层、也更让人头疼的问题:AI coding agents 生成的前端代码,质量参差不齐,风格飘忽不定,离"无懈可击"差得远。
你肯定有过这种体验——让 AI 帮你写一个登录页,第一次生成的按钮圆角是 8px,第二次变成 12px,第三次干脆给你整了个直角。颜色也是,一会儿#3B82F6,一会儿#2563EB,明明说的是同一个品牌蓝。更别提间距了,padding: 16px和padding: 1rem混着用,margin有时候用auto有时候用固定值。单个页面看还行,页面一多,整个项目就像几个人各写各的,完全没有统一的设计语言。
impeccable 就是冲着这个痛点来的。它本质上是一套约束 AI coding agents 输出前端代码的规范层,通过 CLI 工具和浏览器扩展两种形态,让 AI 在生成代码时遵循一套预设的设计系统规则。你可以把它理解成给 AI 戴上了一副"设计规范眼镜"——它还是那个 AI,但看东西、写代码的时候,会按照你定义的规则来。
这个项目适合谁?三类人最需要:一是独立开发者,一个人要管前端所有页面,没时间反复调样式;二是小团队的技术负责人,需要统一多人多 AI 协作时的代码风格;三是对 UI 一致性有强迫症的工程师,看到margin: 13px这种值就浑身难受的那种。
1.2 为什么是 CLI + 浏览器扩展的组合
impeccable 选择 CLI 和浏览器扩展双形态,这个决策背后有很实际的考量。
CLI 解决的是生成阶段的问题。当你在终端里用 codex cli、zcode cli 这类工具让 AI 写代码时,impeccable 的 CLI 会拦截输出,按照规则做一轮校验和修正。比如你定义了"所有间距必须是 4 的倍数",AI 生成了padding: 10px,CLI 就会把它改成padding: 12px或者padding: 8px,具体改成哪个取决于上下文和你的配置。
浏览器扩展解决的是验证阶段的问题。代码写完了,跑起来看效果,这时候扩展会实时检测页面上的元素是否符合规范。间距不对、颜色偏离、字体大小不在预设范围内,扩展会直接在页面上标注出来。这比等到 code review 的时候才发现问题要高效得多。
两者配合的逻辑是:CLI 管"写的时候别写错",扩展管"写完了检查有没有漏网之鱼"。一个在前端拦截,一个在后端兜底,形成闭环。
注意:impeccable 本身不生成代码,它只做约束和校验。你仍然需要 codex cli、zcode cli 或者其他 AI coding agent 来实际写代码。impeccable 是"规则制定者和裁判",不是"运动员"。
1.3 核心概念:什么是"设计令牌"约束
impeccable 的底层机制建立在设计令牌(Design Tokens)之上。这个概念不算新,但 impeccable 把它和 AI coding agents 的结合做得比较彻底。
设计令牌说白了就是把设计决策变成变量。比如:
:root { --color-primary: #2563EB; --color-primary-hover: #1D4ED8; --spacing-unit: 4px; --spacing-sm: calc(var(--spacing-unit) * 2); /* 8px */ --spacing-md: calc(var(--spacing-unit) * 4); /* 16px */ --spacing-lg: calc(var(--spacing-unit) * 6); /* 24px */ --radius-sm: 4px; --radius-md: 8px; --radius-lg: 12px; --font-size-xs: 12px; --font-size-sm: 14px; --font-size-base: 16px; --font-size-lg: 18px; }impeccable 做的事情,就是让 AI 在生成代码时只能使用这些令牌,不能自己发明新值。AI 想写padding: 10px?不行,10 不是 4 的倍数,必须从--spacing-sm(8px)或--spacing-md(16px)里选。AI 想写color: #3B82F6?不行,必须用var(--color-primary)。
这个约束听起来很死板,但实际用下来会发现,正是这种"死板"保证了输出的一致性。而且因为令牌是变量,后期要改品牌色或者调整间距体系,只需要改令牌定义,所有页面自动更新,不用一个个文件去搜替换。
2. 核心细节解析与实操要点
2.1 安装与初始化:从零到能跑起来
impeccable 的安装方式取决于你用的 AI coding agent 生态。目前主流的有两条路径:一条是配合 codex cli 使用,另一条是配合 zcode cli 使用。两者的安装逻辑类似,但命令和配置文件位置有差异。
先说 codex cli 这条线。如果你已经装好了 codex cli,安装 impeccable 的 CLI 部分只需要一条命令:
npm install -g impeccable-cli # 或者用 pnpm pnpm add -g impeccable-cli # 或者用 yarn yarn global add impeccable-cli装完之后,在项目根目录初始化:
impeccable init这个命令会做几件事:创建一个impeccable.config.js配置文件,生成一套默认的设计令牌(就是上面那种 CSS 变量),并且在你的 codex cli 配置里注入一个 pre-commit hook,让 AI 生成的代码在写入文件之前先过一遍 impeccable 的校验。
如果你用的是 zcode cli,流程稍微不同:
zcode plugin install impeccable zcode impeccable initzcode 的插件机制会把 impeccable 注册成一个代码生成后的处理管道,AI 输出先经过 impeccable 处理,再返回给你。
实操心得:安装 codex cli 本身有时候会很慢,特别是网络环境不太理想的时候。我试过用
npm install -g @codex/cli --registry=https://registry.npmmirror.com切换镜像源,速度会快很多。impeccable-cli 本身包不大,安装一般不会卡。
初始化完成后,你会看到项目里多了这些文件:
project-root/ ├── impeccable.config.js # 主配置文件 ├── .impeccable/ │ ├── tokens.css # 设计令牌定义 │ ├── rules.json # 校验规则 │ └── cache/ # 校验缓存 └── src/ └── ... # 你的源码impeccable.config.js是核心,里面定义了校验的严格程度、忽略的文件模式、以及和 AI coding agent 的集成方式。默认配置长这样:
module.exports = { strict: true, // 严格模式,不符合规则的直接报错 autoFix: true, // 自动修复能修的问题 ignore: ['node_modules/**', 'dist/**', '*.min.css'], agents: { codex: { enabled: true, hook: 'pre-write', // 在 AI 写入文件前拦截 }, zcode: { enabled: true, hook: 'post-generate', // 在 AI 生成后、返回前处理 } }, tokens: './.impeccable/tokens.css', rules: './.impeccable/rules.json', };2.2 设计令牌的定制:别直接用默认的
impeccable 自带的默认令牌是一套比较通用的设计系统,但直接用会有问题——它不一定符合你的品牌规范。所以初始化之后第一件事,就是改tokens.css。
改的时候有几个原则:
颜色令牌要分层。不要只定义--color-primary,要定义完整的色阶。比如:
:root { /* 品牌色阶 */ --color-primary-50: #EFF6FF; --color-primary-100: #DBEAFE; --color-primary-200: #BFDBFE; --color-primary-300: #93C5FD; --color-primary-400: #60A5FA; --color-primary-500: #3B82F6; /* 主色 */ --color-primary-600: #2563EB; --color-primary-700: #1D4ED8; --color-primary-800: #1E40AF; --color-primary-900: #1E3A8A; /* 语义化令牌 */ --color-primary: var(--color-primary-600); --color-primary-hover: var(--color-primary-700); --color-primary-active: var(--color-primary-800); --color-primary-disabled: var(--color-primary-300); }这样 AI 在生成 hover 状态时,会自动用--color-primary-hover,而不是随便挑一个蓝色。
间距令牌要用乘法体系。不要定义--spacing-1: 4px、--spacing-2: 8px这种,而是定义一个基准单位,其他都基于它计算:
:root { --spacing-unit: 4px; --spacing-0: 0; --spacing-1: calc(var(--spacing-unit) * 1); /* 4px */ --spacing-2: calc(var(--spacing-unit) * 2); /* 8px */ --spacing-3: calc(var(--spacing-unit) * 3); /* 12px */ --spacing-4: calc(var(--spacing-unit) * 4); /* 16px */ --spacing-5: calc(var(--spacing-unit) * 5); /* 20px */ --spacing-6: calc(var(--spacing-unit) * 6); /* 24px */ --spacing-8: calc(var(--spacing-unit) * 8); /* 32px */ --spacing-10: calc(var(--spacing-unit) * 10); /* 40px */ --spacing-12: calc(var(--spacing-unit) * 12); /* 48px */ --spacing-16: calc(var(--spacing-unit) * 16); /* 64px */ }这样 AI 生成padding: 10px的时候,impeccable 会检测到 10 不是 4 的倍数,自动修正为最近的合法值(8px 或 12px)。
字体大小要限制档位。不要给 AI 无限的选择,只给几个标准档:
:root { --font-size-xs: 12px; --font-size-sm: 14px; --font-size-base: 16px; --font-size-lg: 18px; --font-size-xl: 20px; --font-size-2xl: 24px; --font-size-3xl: 30px; --font-size-4xl: 36px; }AI 想写font-size: 15px?不行,必须从这些档位里选。
注意事项:改完 tokens.css 之后,一定要跑一遍
impeccable validate检查现有代码有没有违规。我见过有人改完令牌直接让 AI 继续写新页面,结果新旧页面风格完全对不上,因为旧页面还在用老的硬编码值。
2.3 规则配置:哪些能自动修,哪些必须人工介入
rules.json定义了具体的校验规则。impeccable 内置了几十种规则,但常用的就那么十几种。我整理了一个速查表:
| 规则名 | 作用 | 能否自动修复 | 建议严格度 |
|---|---|---|---|
no-hardcoded-color | 禁止硬编码颜色值 | 能,替换为最近令牌 | error |
no-hardcoded-spacing | 禁止硬编码间距 | 能,修正为最近合法值 | error |
no-hardcoded-font-size | 禁止硬编码字号 | 能,修正为最近档位 | error |
no-magic-number | 禁止魔法数字 | 部分能,简单场景可修 | warn |
prefer-token-over-value | 优先使用令牌 | 能 | error |
consistent-border-radius | 圆角一致性 | 能 | warn |
no-important | 禁止!important | 不能,需人工判断 | error |
max-nesting-depth | 最大嵌套深度 | 不能 | warn |
no-inline-style | 禁止内联样式 | 不能 | warn |
consistent-naming | 类名命名一致性 | 不能 | warn |
配置的时候,error级别的规则会阻止 AI 写入文件,warn级别的只会提示但不会拦截。我的建议是:颜色、间距、字号这三类必须设为 error,因为它们是 UI 一致性的基石,而且自动修复的准确率很高。no-important也建议设为 error,因为!important一旦泛滥,后期维护就是噩梦。
no-magic-number设为 warn 就行,因为有些数字确实有特殊含义(比如z-index: 9999),强制修正反而会出问题。
{ "rules": { "no-hardcoded-color": { "level": "error", "autoFix": true }, "no-hardcoded-spacing": { "level": "error", "autoFix": true }, "no-hardcoded-font-size": { "level": "error", "autoFix": true }, "no-magic-number": { "level": "warn", "autoFix": false }, "prefer-token-over-value": { "level": "error", "autoFix": true }, "consistent-border-radius": { "level": "warn", "autoFix": true }, "no-important": { "level": "error", "autoFix": false }, "max-nesting-depth": { "level": "warn", "maxDepth": 3 }, "no-inline-style": { "level": "warn", "autoFix": false }, "consistent-naming": { "level": "warn", "pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$" } } }2.4 浏览器扩展的安装与配置
浏览器扩展的安装比 CLI 简单,但配置项更细。以 Chrome 为例,从扩展商店装好 impeccable 之后,点开扩展图标,会看到一个配置面板。
面板里最重要的三个设置:
令牌源地址。扩展需要知道你的设计令牌定义在哪里。有两种方式:一种是直接粘贴tokens.css的内容,另一种是填一个 URL,扩展会定期拉取。推荐第二种,这样令牌更新后扩展会自动同步。
检测模式。有三种模式可选:strict(严格模式,任何违规都标红)、advisory(建议模式,只标黄不标红)、silent(静默模式,只在控制台输出)。开发阶段建议用strict,上线前切到advisory做最后检查。
忽略选择器。有些第三方组件的样式你改不了,比如嵌入的地图、支付表单等。把这些组件的选择器填进忽略列表,扩展就不会去检测它们。
配置好之后,打开你的项目页面,扩展会自动扫描所有元素。违规的元素会被高亮,鼠标悬停会显示具体问题:
元素: <button class="submit-btn"> 问题: padding 使用了硬编码值 10px 建议: 改为 var(--spacing-2) (8px) 或 var(--spacing-3) (12px) 规则: no-hardcoded-spacing点击"应用建议",扩展会直接修改页面上的样式(仅用于预览,不会改源码)。确认没问题后,回到代码里手动改,或者让 CLI 批量修复。
实操心得:浏览器扩展在检测动态生成的元素时偶尔会漏。比如 React 组件条件渲染出来的弹窗,扩展可能来不及扫描。这时候可以在控制台手动触发一次扫描:
window.__impeccable__.scan()。这个命令在文档里没写,是我翻源码发现的。
3. 实操过程与核心环节实现
3.1 完整工作流:从让 AI 写代码到最终验收
这一节我把整个流程串起来,从你敲下命令让 AI 写代码,到最终页面验收,中间每一步都拆开讲。
第一步:启动 AI coding agent 并加载 impeccable 上下文
如果你用 codex cli,启动命令是:
codex cli --project ./my-project进入交互界面后,先加载 impeccable 的规则上下文:
/impeccable load这个命令会让 codex cli 读取.impeccable/tokens.css和rules.json,并在后续的代码生成中应用这些规则。你会看到类似这样的输出:
[impeccable] Loaded 48 design tokens [impeccable] Loaded 10 rules (6 error, 4 warn) [impeccable] Ready to enforce第二步:让 AI 生成代码
现在你可以正常让 AI 写代码了。比如:
生成一个用户登录表单,包含邮箱、密码输入框和提交按钮codex cli 会生成代码,但在写入文件之前,impeccable 会拦截并校验。假设 AI 生成了这样的代码:
.login-form { padding: 20px; background: #ffffff; border-radius: 6px; } .login-form input { padding: 10px 14px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 15px; } .login-form button { padding: 12px 24px; background: #3b82f6; color: #ffffff; border-radius: 6px; font-size: 16px; }impeccable 校验后会输出:
[impeccable] Found 7 violations: - .login-form padding: 20px → var(--spacing-5) (20px) ✓ auto-fixed - .login-form border-radius: 6px → var(--radius-sm) (4px) or var(--radius-md) (8px) ⚠ ambiguous - .login-form input padding: 10px 14px → var(--spacing-2) var(--spacing-3) (8px 12px) ✓ auto-fixed - .login-form input border-color: #d1d5db → var(--color-gray-300) ✓ auto-fixed - .login-form input font-size: 15px → var(--font-size-sm) (14px) ✓ auto-fixed - .login-form button background: #3b82f6 → var(--color-primary) ✓ auto-fixed - .login-form button border-radius: 6px → var(--radius-sm) or var(--radius-md) ⚠ ambiguous注意border-radius: 6px被标记为 ambiguous,因为 6px 在 4px 和 8px 之间,impeccable 不确定该往哪边修。这种情况需要你手动决定。我一般会看上下文——如果这个元素是卡片或者按钮,用 8px 更合适;如果是输入框,4px 更常见。
第三步:处理无法自动修复的问题
对于 ambiguous 或者无法自动修复的问题,impeccable 会暂停写入,等你确认。你可以:
- 输入
fix 1选择第一个建议 - 输入
fix 2选择第二个建议 - 输入
skip跳过,保留原值(不推荐) - 输入
edit手动输入一个值
处理完之后,代码才会真正写入文件。
第四步:浏览器扩展验收
代码写完了,跑起来看效果。打开页面,impeccable 扩展会自动扫描。如果还有漏网的违规,扩展会在页面上标注。点击标注可以看到详情,并且可以直接在 DevTools 里看到修正后的样式对比。
第五步:批量修复存量代码
如果是老项目接入 impeccable,存量代码肯定一堆违规。这时候用 CLI 的批量修复命令:
impeccable fix --all --dry-run先 dry-run 看一遍会改哪些地方,确认没问题后去掉--dry-run实际执行:
impeccable fix --all这个命令会遍历所有 CSS/SCSS/LESS 文件,按照规则自动修复。修复不了的会列出来,需要人工处理。
3.2 参数计算:间距和字号的具体修正逻辑
impeccable 修正硬编码值时,用的是一套最近合法值算法。理解这个算法,你就能预判它会怎么改,避免出现"改完还不如不改"的情况。
以间距为例,假设基准单位是 4px,合法值集合是{0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64}。AI 生成了一个padding: 18px。
计算过程:
- 找到小于等于 18 的最大合法值:16
- 找到大于等于 18 的最小合法值:20
- 计算距离:|18-16|=2,|18-20|=2
- 距离相等时,默认取较小值(可以通过配置改为取较大值)
所以18px会被修正为16px。
再比如padding: 22px:
- 小于等于 22 的最大合法值:20
- 大于等于 22 的最小合法值:24
- 距离:|22-20|=2,|22-24|=2
- 距离相等,取较小值 20px
padding: 26px:
- 小于等于 26 的最大合法值:24
- 大于等于 26 的最小合法值:32
- 距离:|26-24|=2,|26-32|=6
- 取距离更近的 24px
字号的计算逻辑类似,但合法值集合不同。假设合法字号是{12, 14, 16, 18, 20, 24, 30, 36},AI 生成font-size: 15px:
- 小于等于 15 的最大合法值:14
- 大于等于 15 的最小合法值:16
- 距离:|15-14|=1,|15-16|=1
- 距离相等,取较小值 14px
font-size: 17px:
- 小于等于 17 的最大合法值:16
- 大于等于 17 的最小合法值:18
- 距离:|17-16|=1,|17-18|=1
- 取较小值 16px
font-size: 19px:
- 小于等于 19 的最大合法值:18
- 大于等于 19 的最小合法值:20
- 距离:|19-18|=1,|19-20|=1
- 取较小值 18px
注意:这个"距离相等取较小值"的策略可以通过配置改成"取较大值"或者"报错让用户决定"。在
impeccable.config.js里设置tieBreaker: 'smaller' | 'larger' | 'ask'。我一般用ask,因为有些场景下取小会显得太挤,取大又太松,还是人工判断更靠谱。
3.3 和 codex cli 的深度集成:hook 机制详解
impeccable 和 codex cli 的集成是通过 hook 实现的。codex cli 在代码生成的生命周期里暴露了几个 hook 点,impeccable 注册了其中的pre-write和post-generate。
pre-writehook 在 AI 准备写入文件之前触发。impeccable 拿到 AI 生成的代码,做一轮校验和自动修复,然后把修正后的代码交给 codex cli 写入。如果校验失败且无法自动修复,hook 会阻止写入,并把问题返回给 AI,让 AI 重新生成。
post-generatehook 在 AI 生成完但还没返回给用户时触发。这个 hook 主要用于记录和统计,比如记录这次生成触发了多少条规则、自动修复了多少处、还有多少需要人工处理。
配置 hook 的地方在impeccable.config.js:
module.exports = { agents: { codex: { enabled: true, hooks: { 'pre-write': { enabled: true, onFailure: 'block', // block | warn | ignore }, 'post-generate': { enabled: true, logLevel: 'info', // info | debug | silent } } } } };onFailure: 'block'是最严格的,校验不通过就不让写。如果你刚开始用,建议先设成warn,让 AI 先写进去,你手动看看问题在哪,熟悉了再改成block。
3.4 浏览器扩展的高级用法:自定义检测规则
浏览器扩展默认只加载rules.json里的规则,但它其实支持在运行时动态添加规则。打开 DevTools,在 Console 里输入:
window.__impeccable__.addRule({ name: 'no-pure-black', selector: '*', check: (el) => { const color = getComputedStyle(el).color; return color !== 'rgb(0, 0, 0)'; }, message: '避免使用纯黑色文字,建议用 #1F2937 或 var(--color-gray-900)', level: 'warn' });这条规则会检测页面上所有使用纯黑文字的元素。纯黑在屏幕上对比度太高,长时间阅读容易疲劳,一般建议用深灰色代替。
添加的规则只在当前页面会话有效,刷新就没了。如果要持久化,需要写进rules.json然后重新加载扩展。
实操心得:自定义规则特别适合做项目特定的检查。比如我们项目要求所有可点击元素的点击区域不小于 44x44px(移动端可访问性标准),我就加了一条规则自动检测。这种项目特有的约束,impeccable 内置规则覆盖不到,但自定义规则可以轻松实现。
4. 常见问题与排查技巧实录
4.1 安装和初始化阶段的坑
问题一:codex cli 安装很慢或者卡住
这是最常见的问题。codex cli 的包体积不小,加上依赖,首次安装可能要几分钟。如果卡住不动,先检查网络,然后试试切换镜像源:
npm config set registry https://registry.npmmirror.com npm install -g @codex/cli如果还是慢,可以试试用pnpm或者yarn,它们的并行下载机制有时候会快一些。
问题二:impeccable init 报错 "config file already exists"
说明项目里已经有impeccable.config.js了。如果你想重新初始化,先删掉旧文件:
rm impeccable.config.js rm -rf .impeccable/ impeccable init或者用--force参数强制覆盖:
impeccable init --force问题三:浏览器扩展装了但页面上没反应
先检查扩展是否启用,然后看扩展的配置里令牌源地址填了没。如果令牌源地址是空的,扩展不知道你的设计令牌是什么,就不会做任何检测。另外,有些页面是chrome://或者about:开头的,扩展没有权限访问,这是正常的。
4.2 使用过程中的典型问题
问题四:AI 生成的代码被 impeccable 改得面目全非
这种情况通常是因为令牌体系定义得太粗。比如你只定义了--spacing-sm: 8px和--spacing-lg: 24px,中间没有 12px、16px、20px 的档位。AI 生成padding: 16px,impeccable 只能改成 8px 或者 24px,两个都不太对。
解决办法是把令牌体系做细。间距至少要有 4、8、12、16、20、24、32 这几档,字号至少要有 12、14、16、18、20、24 这几档。档位越细,修正后的值越接近 AI 原本的意图。
问题五:某些元素的样式被误判
比如第三方组件库的按钮,它的样式是组件库自带的,你改不了。但 impeccable 不知道,还是会去检测和修正。
解决办法是在impeccable.config.js的ignore里加上这些组件的选择器:
module.exports = { ignore: [ 'node_modules/**', '.ant-btn', // Ant Design 按钮 '.el-button', // Element UI 按钮 '[data-third-party]', // 自定义标记 ] };浏览器扩展里也有对应的忽略列表配置,两边都要加。
问题六:自动修复后样式反而错了
impeccable 的自动修复是基于规则的,它不理解上下文。比如margin: -10px这种负值,修正逻辑和正值不一样。如果基准单位是 4px,-10px会被修正为-8px或-12px,但你可能原本想要的就是-10px这种非标准值来实现某种特殊效果。
遇到这种情况,可以在代码里加注释告诉 impeccable 跳过:
.special-offset { /* impeccable-ignore-next-line */ margin: -10px; }或者用impeccable-ignore块注释跳过一段:
/* impeccable-ignore-start */ .legacy-component { padding: 13px; margin: 7px; } /* impeccable-ignore-end */4.3 常见问题速查表
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| CLI 命令找不到 | 没装全局或 PATH 没配 | which impeccable | 重新npm install -g或检查 PATH |
| 扩展不检测 | 令牌源未配置 | 看扩展配置面板 | 填入 tokens.css 路径或 URL |
| 修正后样式错乱 | 令牌档位太粗 | 检查 tokens.css | 增加中间档位 |
| AI 代码被阻止写入 | 有 error 级违规未修复 | 看 CLI 输出 | 手动修复或调整规则级别 |
| 扩展漏检动态元素 | 扫描时机问题 | 控制台手动扫描 | window.__impeccable__.scan() |
| 第三方组件被误判 | 未加入忽略列表 | 看违规元素选择器 | 加入 ignore 配置 |
| 负值修正错误 | 负值处理逻辑不同 | 检查修正结果 | 用 ignore 注释跳过 |
| 令牌更新后旧页面不生效 | 缓存未清除 | 看 .impeccable/cache | impeccable cache clear |
4.4 独家避坑技巧
技巧一:渐进式接入,别一上来就 strict
老项目接入 impeccable,如果直接开 strict 模式,你会发现满屏都是违规,根本改不过来。正确的做法是:
- 第一周:只开
warn,让 impeccable 报告问题但不阻止写入,你心里有个数 - 第二周:把颜色和间距规则改成
error,其他保持warn - 第三周:把字号和圆角也改成
error - 第四周:全量 strict
这样一步步来,每周修一批,压力小很多。
技巧二:用impeccable diff看 AI 到底改了什么
impeccable 有一个不太起眼的命令impeccable diff,它会显示 AI 生成的原始代码和经过 impeccable 修正后的代码之间的差异。这个命令在调试"为什么 AI 写的和我看到的不一样"时特别有用。
impeccable diff --last输出类似:
- padding: 18px; + padding: var(--spacing-4); /* 16px */ - color: #3b82f6; + color: var(--color-primary); - font-size: 15px; + font-size: var(--font-size-sm); /* 14px */技巧三:给 AI 的 prompt 里直接提 impeccable
虽然 impeccable 会自动修正,但如果你在 prompt 里就告诉 AI 用令牌,修正的工作量会小很多。比如:
生成一个登录表单,使用项目定义的设计令牌(--color-primary, --spacing-*, --font-size-*),不要硬编码任何颜色、间距和字号。这样 AI 一开始就会用var(--color-primary)而不是#3b82f6,impeccable 需要修正的地方就少了。
技巧四:定期跑impeccable audit做全面体检
impeccable audit会扫描整个项目,生成一份详细的合规报告:
impeccable audit --format=html --output=./audit-report.html报告里会列出:总文件数、违规文件数、违规总数、按规则分类的统计、按文件分类的统计、以及修复建议。我一般每周跑一次,看看合规率有没有提升。
技巧五:团队协作时统一令牌版本
如果团队多人协作,每个人的tokens.css版本可能不一样,导致 AI 生成的代码风格不一致。解决办法是把.impeccable/目录纳入版本控制,并且约定:任何人修改令牌都必须走 code review。令牌是设计系统的基石,不能随便改。
5. 影响范围与适用场景分析
5.1 对个人开发者的价值
对独立开发者来说,impeccable 最大的价值是省时间。一个人做项目,前端后端运维全包,最烦的就是调样式。有了 impeccable,AI 生成的代码直接就是符合规范的,不用再一个个文件去改padding和color。
我自己的项目接入 impeccable 之后,UI 相关的返工率大概降了六成。以前 AI 写完一个页面,我要花半小时调样式;现在基本不用调,生成出来就能用。省下来的时间可以去做更有价值的事,比如优化业务逻辑、写测试、或者干脆早点下班。
另一个价值是降低对设计系统的记忆负担。你不用记住--color-primary到底是#2563EB还是#3B82F6,impeccable 会帮你记住。你只需要在 tokens.css 里定义一次,之后所有地方都用令牌引用。
5.2 对团队协作的影响
团队场景下,impeccable 解决的是一个更棘手的问题:多人多 AI 协作时的风格漂移。
想象一个场景:团队里三个人,A 用 codex cli,B 用 zcode cli,C 用另一个 AI 工具。三个人让 AI 写同一个页面的不同部分,如果没有统一约束,最后拼起来就是三种风格。A 的按钮圆角 8px,B 的 12px,C 的 6px。A 的主色#3B82F6,B 的#2563EB,C 的#1D4ED8。虽然都是蓝色,但放在一起就是不对劲。
impeccable 通过统一的令牌和规则,把三个人的输出拉到同一个标准上。不管用什么 AI 工具,生成的代码都遵循同一套设计系统。这对团队来说,省下的不仅是调样式的时间,还有沟通成本——不用再争论"这个按钮到底该用哪个蓝"。
5.3 适用场景与不适用场景
impeccable 最适合的场景:
- 中大型前端项目,页面多、组件多,UI 一致性要求高
- 多人协作项目,需要统一不同开发者和不同 AI 工具的输出
- 有设计系统的项目,已经有明确的颜色、间距、字号规范
- 快速迭代项目,AI 生成代码频率高,需要自动化约束
不太适合的场景:
- 一次性脚本或 Demo,用完就扔,没必要上约束
- 高度定制化的设计,每个页面都是独一无二的,没有统一规范可循
- 纯后端项目,不涉及前端样式
- 设计系统还没定下来的项目,令牌都没定义好,impeccable 也无从约束
5.4 和其他类似工具的对比
市面上做前端代码规范的工具不少,但和 impeccable 定位接近的不多。ESLint 管的是 JavaScript 逻辑,Stylelint 管的是 CSS 语法,Prettier 管的是格式化。impeccable 管的是设计令牌的使用,这是前面几个工具都不覆盖的领域。
| 工具 | 管什么 | 和 impeccable 的关系 |
|---|---|---|
| ESLint | JS/TS 逻辑和语法 | 互补,各管各的 |
| Stylelint | CSS 语法和部分规范 | 有重叠,但 impeccable 更侧重令牌 |
| Prettier | 代码格式化 | 互补,Prettier 管格式,impeccable 管值 |
| impeccable | 设计令牌使用 | 专注令牌约束和 AI 集成 |
实际项目中,这几个工具可以同时用。ESLint 管逻辑,Stylelint 管语法,Prettier 管格式,impeccable 管令牌。各司其职,互不冲突。
6. 进阶玩法与扩展思路
6.1 把 impeccable 接入 CI/CD 流水线
impeccable 不只能在本地用,还可以接入 CI/CD。在 GitHub Actions 里加一个 step:
- name: Impeccable Audit run: | npm install -g impeccable-cli impeccable audit --format=json --output=./audit.json impeccable check --fail-on-errorimpeccable check --fail-on-error会在有 error 级违规时返回非零退出码,从而让 CI 失败。这样就能保证合并到主分支的代码都是符合规范的。
如果不想让 CI 太严格,可以只对新增文件做检查:
impeccable check --changed-only --fail-on-error--changed-only只检查 git diff 里改动的文件,存量代码不管。这样新代码有保障,老代码慢慢改。
6.2 和设计工具的联动
impeccable 的令牌定义是 CSS 格式,但设计工具(如 Figma)用的是自己的格式。如果能把 Figma 的设计令牌自动同步到tokens.css,就能保证设计和代码完全一致。
思路是:用 Figma 的 API 导出设计令牌为 JSON,然后写一个脚本把 JSON 转成 CSS 变量,写入tokens.css。这样设计师在 Figma 里改了颜色,跑一下脚本,代码里的令牌就更新了。
// sync-tokens.js const figmaTokens = require('./figma-tokens.json'); const cssLines = [':root {']; for (const [name, value] of Object.entries(figmaTokens)) { cssLines.push(` --${name}: ${value};`); } cssLines.push('}'); require('fs').writeFileSync('./.impeccable/tokens.css', cssLines.join('\n')); console.log('Tokens synced from Figma');这个脚本可以放在 pre-commit hook 里,每次提交前自动跑一次。
6.3 自定义规则开发
impeccable 支持自定义规则,规则文件是一个 JavaScript 模块:
// .impeccable/custom-rules/no-small-tap-target.js module.exports = { name: 'no-small-tap-target', selector: 'button, a, [role="button"]', check: (el) => { const rect = el.getBoundingClientRect(); return rect.width >= 44 && rect.height >= 44; }, message: '可点击元素的点击区域应不小于 44x44px', level: 'warn', autoFix: false, };然后在rules.json里引用:
{ "customRules": [ "./.impeccable/custom-rules/no-small-tap-target.js" ] }自定义规则可以覆盖很多项目特有的约束,比如"所有图片必须有 alt 属性"、"所有表单必须有 label"、"禁止使用position: fixed"等等。
6.4 性能优化:大项目下的扫描速度
项目大了之后,impeccable 的扫描可能会变慢。几个优化手段:
增量扫描。只扫描改动的文件,而不是全量扫描:
impeccable check --changed-only缓存。impeccable 会把扫描结果缓存到.impeccable/cache/,下次扫描时如果文件没变,直接用缓存:
impeccable check --cache并行扫描。多核机器上可以开并行:
impeccable check --parallel=4排除大文件。有些第三方库的 CSS 文件很大,扫描它们纯属浪费时间。在ignore里排除:
ignore: [ 'node_modules/**', 'dist/**', '**/*.min.css', 'vendor/**', ]我实测下来,一个中等规模的项目(大概 200 个 CSS 文件),全量扫描要 30 秒左右,增量扫描只要 2-3 秒。加上缓存之后,重复扫描基本是秒级完成。
6.5 未来可能的扩展方向
impeccable 目前主要聚焦在 CSS 层面,但设计令牌的概念可以扩展到更多领域。比如:
间距和布局的响应式约束。不同断点下的间距规则可能不同,impeccable 可以支持按断点配置令牌。
动画和过渡的约束。过渡时长、缓动函数也可以令牌化,避免 AI 生成transition: all 0.3s ease这种千篇一律的写法。
暗色模式的令牌映射。暗色模式下颜色令牌需要一套映射关系,impeccable 可以自动处理这个映射。
组件级别的令牌约束。不同组件(按钮、卡片、输入框)可能有不同的令牌使用规则,impeccable 可以按组件类型做更细粒度的约束。
这些方向有些已经在 roadmap 里了,有些还在讨论。但核心思路是一致的:把设计决策变成可约束的规则,让 AI 在规则内自由发挥。
我在实际使用中最大的体会是,impeccable 这类工具的价值不在于它现在有多完善,而在于它代表了一种思路——AI 生成代码的质量,不能只靠 AI 自己,还需要外部的约束层。就像编译器需要类型检查,AI 写前端也需要设计规范检查。这个思路可以迁移到很多其他领域,比如 AI 写后端代码时的 API 规范约束、AI 写 SQL 时的查询规范约束等等。impeccable 只是这个思路在前端设计领域的一个实现,但它打开了一扇门。