1. 从"impeccable"这个词说起:它到底想解决什么问题
第一次看到"impeccable"这个词被拿来命名一个开发工具,我的反应是:这名字起得挺狂。impeccable 在英文里的意思是"无可挑剔的、完美的",一个工具敢叫这个名字,要么是营销噱头,要么是真的在某个环节上做到了极致。花了两周时间把它揉进我自己的前端工作流之后,我的判断是:它属于后者,但"完美"的不是它生成的代码,而是它试图解决的那个问题——AI 写出来的前端代码,为什么总是差那么一口气。
如果你最近半年用过任何 AI coding agent,不管是终端里的 codex cli、zcode cli,还是编辑器里的各种插件,你大概率有过这种体验:让它写一个登录页,它给你吐出来的东西能跑,但那个间距、那个圆角、那个按钮的 hover 状态,总让你觉得"这是机器做的"。你会花大量时间去微调,调到最后发现,省下来的时间又还回去了。impeccable 切入的正是这个缝隙——它不是一个代码生成器,而是一个前端设计质量的约束层,通过 CLI 和浏览器扩展两种形态,把"设计品味"这件事变成可执行、可校验的规则。
所以这篇文章适合谁看?如果你是前端工程师,天天和 AI 生成的 UI 代码打交道,想让产出直接能用而不是"能跑就行",那这篇值得你花时间。如果你是团队里负责设计规范落地的人,想让 AI 工具遵守你们的设计系统而不是各写各的,impeccable 的思路也值得参考。哪怕你只是想搞清楚"impeccable 如何使用"这个最基础的问题,我也会从安装一路讲到实战调优。下面所有内容都是基于我自己的实操记录整理的,涉及参数和配置的地方我会把计算逻辑讲清楚,方便你按自己的项目改。
2. 核心思路拆解:为什么是"约束层"而不是"生成器"
2.1 一个反直觉的判断:AI 不缺生成能力,缺的是审美约束
市面上绝大多数 AI 前端工具的定位都是"生成"——你描述需求,它输出代码。这个方向本身没错,但问题在于,生成能力的提升是有天花板的,而审美一致性这件事,靠堆模型参数是解决不了的。原因很简单:设计品味是上下文相关的。同一个按钮,在极简风格的 SaaS 后台里应该是 4px 圆角、无阴影,在电商促销页里可能就需要 12px 圆角加渐变。模型不知道你的项目属于哪种语境,它只能给你一个"平均意义上还行"的结果。
impeccable 的聪明之处在于,它不跟生成能力较劲,而是把自己定位成一个后置的约束层。你可以继续用你习惯的 codex cli 或者 zcode cli 去生成代码,impeccable 负责在代码落地之前,用一套可配置的设计规则去"卡"一遍。这就像装修:AI 是那个能快速把墙砌起来的施工队,impeccable 是那个拿着水平仪和色卡验收的监理。施工队再快,没有监理,墙面就是歪的。
这个定位带来的直接好处是解耦。你换生成工具,约束层不用动;你改设计规范,生成工具也不用重训。我实测下来,这种解耦让整个工作流的稳定性提升非常明显——以前 AI 工具一升级,之前调好的 prompt 全废了,现在至少约束层是稳定的。
2.2 CLI 与浏览器扩展:两种形态各自解决什么场景
impeccable 提供了两种使用形态,很多人一开始会困惑到底该用哪个。我的经验是:它们解决的是工作流里两个不同的时间点。
CLI 形态面向的是代码提交前。你在终端里跑一条命令,它扫描你项目里的组件文件,按照配置好的规则输出一份报告,告诉你哪些地方违反了设计约束。这个场景适合接入 CI,或者在你 commit 之前手动跑一遍。它的优势是能覆盖整个代码库,批量发现问题。
浏览器扩展形态面向的是运行时。你打开本地开发服务器,扩展会实时分析页面上渲染出来的元素,把违反约束的地方直接标注在页面上。这个场景适合调试——有些问题在代码里看不出来,但渲染出来一眼就发现间距不对。扩展的好处是所见即所得,坏处是只能看当前页面。
我自己的用法是:日常开发开着扩展,边写边看;提交前跑一遍 CLI,确保没有漏网的。两者配合,基本能把设计质量问题挡在合并之前。
2.3 为什么这套方案值得投入学习成本
有人可能会说,我直接写个 ESLint 规则不就行了?这个想法我试过,结论是:ESLint 管得了语法,管不了视觉。你可以用 ESLint 禁止硬编码颜色值,但你没法用它判断"这个间距在视觉上是否协调"。impeccable 的价值在于它把视觉层面的判断也纳入了可执行的范围,虽然它底层可能还是靠解析 CSS 属性值,但它组织的规则维度是围绕"设计质量"而不是"代码规范"来的。
这个区别很关键。代码规范解决的是"能不能维护",设计质量解决的是"好不好看"。前者是工程问题,后者是产品问题。impeccable 把后者也变成了工程问题,这才是它值得学的地方。
3. 环境准备与安装:从零把 impeccable 跑起来
3.1 前置依赖检查:别跳过这一步
在装 impeccable 之前,有几个前置条件必须先确认,不然装到一半报错会很浪费时间。我踩过的坑基本都集中在这一步。
首先是Node.js 版本。impeccable 的 CLI 依赖 Node 环境,我实测下来 18.x 和 20.x 都能跑,但 16.x 会在解析某些 ESM 模块时报错。你可以用node -v确认一下,如果低于 18,建议先用 nvm 切一个版本。这里有个细节:如果你同时装了多个 Node 版本,注意确认which node指向的是你想用的那个,我有一次就是因为全局装在了旧版本上,跑命令一直提示找不到模块。
其次是包管理器。npm、pnpm、yarn 都行,但如果你项目用的是 pnpm 的 workspace 模式,建议把 impeccable 装在根目录而不是子包里,不然 CLI 扫描的时候会漏掉其他包的文件。这个是我在一个 monorepo 项目里踩的坑,扫描结果少了一大半,排查了半天才发现是安装位置的问题。
最后是浏览器扩展的宿主。扩展目前对 Chromium 内核的浏览器支持最好,如果你主力用 Firefox,部分实时标注功能可能不完整。这个不是 bug,是内核差异导致的,官方文档里也有说明。
3.2 CLI 安装的两种方式与选择逻辑
impeccable 的 CLI 有两种安装方式,选哪种取决于你的使用场景。
第一种是全局安装:
npm install -g impeccable-cli全局装的好处是任何目录下都能直接敲impeccable命令,适合你需要在多个项目之间切换的场景。坏处是版本管理麻烦,不同项目可能需要不同版本的规则集。
第二种是项目内安装:
npm install -D impeccable-cli装在项目里,通过npx impeccable调用。这种方式的好处是版本跟着项目走,团队协作时大家用的规则集完全一致,不会出现"我这边能过你那边报错"的情况。我现在的做法是:个人探索用全局,正式项目一律项目内安装,并且把版本号锁死在 package.json 里。
提示:如果你所在的环境对全局安装有权限限制,项目内安装是更稳妥的选择,不需要 sudo 也能跑起来。
3.3 浏览器扩展的加载与首次配置
扩展的安装方式和 CLI 不太一样,它不是从应用商店装的,而是需要手动加载。具体步骤是:先下载扩展包,解压到一个你不会随手删掉的目录,然后在浏览器的扩展管理页面打开"开发者模式",选择"加载已解压的扩展程序",指向刚才解压的目录。
这里有个非常容易踩的坑:解压后的目录不要放在临时文件夹里,因为浏览器会记住这个路径,你哪天清理磁盘把它删了,扩展就失效了,而且失效的时候不会给你明显提示,你只会觉得"怎么突然不标注了"。我第一次就吃了这个亏,后来固定放在~/tools/impeccable-ext下面,再没出过问题。
首次配置的时候,扩展会问你要连接的本地服务地址。默认是localhost加一个端口,如果你本地开发服务器改过端口,记得同步改一下。配置完之后,打开你的项目页面,扩展图标上会出现一个小角标,显示当前页面检测到的问题数量。如果角标一直是 0,先别高兴,大概率是没连上,检查一下服务地址和端口。
4. 核心配置解析:规则集是怎么组织的
4.1 配置文件的结构与关键字段
impeccable 的核心是一份配置文件,通常叫impeccable.config.js或者.impeccablerc。这份文件决定了它用什么规则去校验你的代码。我把它拆成几个关键部分来讲。
第一部分是design tokens,也就是设计变量。这里你定义项目里允许使用的颜色、间距、圆角、字号等基础值。比如:
module.exports = { tokens: { spacing: [4, 8, 12, 16, 24, 32, 48, 64], radius: [0, 4, 8, 12, 16, 9999], colors: { primary: '#2563eb', danger: '#dc2626', // ... } } }这个 tokens 列表就是后续所有校验的基准。任何代码里出现的间距值如果不在这份列表里,就会被标记出来。这个设计的逻辑是:设计系统的一致性,本质上就是"只用有限的几个值"。人眼对 13px 和 14px 的间距几乎分辨不出来,但代码里混用这两个值,维护起来就是灾难。impeccable 通过强制收敛取值,把这种隐性混乱显性化。
第二部分是rules,规则集。每条规则指定校验什么、严重程度如何。比如你可以配一条规则,禁止在组件里直接写十六进制颜色值,必须引用 token。严重程度分 error、warn、info 三档,error 会导致 CLI 返回非零退出码,适合接入 CI 卡点。
第三部分是ignore,忽略列表。有些第三方组件或者自动生成的代码你不想校验,就在这里排除。我的经验是,忽略列表要尽量精确,不要图省事整个目录排除,不然容易漏掉真正的问题。
4.2 间距与圆角的取值收敛:一个具体的计算过程
很多人配 tokens 的时候是拍脑袋定的,其实这里面有数学逻辑。我拿间距举例说明。
假设你的基础字号是 16px,那么一个合理的间距阶梯应该基于一个基准单位做倍数展开。业界常用的基准是 4px 或 8px。我选 4px 作为基准,然后按 1、2、3、4、6、8、12、16 的倍数展开,得到的就是 4、8、12、16、24、32、48、64 这一串。为什么是这几个倍数而不是线性递增?因为视觉感知是对数级的,间距从 4 到 8 的感知差异,和从 32 到 64 的感知差异是接近的。线性递增会导致大间距区域选项过密,小间距区域选项过疏。
圆角也是同理。0 表示直角,4 到 8 是"微圆角",适合按钮和输入框,12 到 16 是"明显圆角",适合卡片,9999 是"全圆角",适合胶囊按钮和头像。把这几个值定下来,团队里就不会出现有人用 6px 有人用 7px 的情况。
注意:tokens 一旦定下来,改动的成本很高,因为所有引用它的地方都要跟着调。所以第一版宁可少定几个值,后面按需增加,也不要一上来就定一大堆用不上的。
4.3 规则严重程度的分配策略
error、warn、info 这三档怎么分配,直接决定了 impeccable 在你工作流里的存在感。我的策略是这样的:
error 档只放那些"绝对不允许"的规则,比如硬编码颜色值、使用未定义的 token、间距值不在列表里。这些问题的共同点是:一旦出现,就说明代码脱离了设计系统的管控,必须修。
warn 档放那些"最好别这样但可以商量"的规则,比如某个组件的内边距和同类组件不一致、某个交互状态缺少 hover 样式。这些问题不影响功能,但影响一致性,适合在 code review 时提醒。
info 档放那些"仅供参考"的规则,比如某个地方的间距可以用更接近的 token 值。这类问题不强制修,但列出来能帮你发现优化空间。
这个分配的逻辑是:error 太多会让人麻木,warn 太多会让人烦躁,info 太多会让人无视。我一开始把所有规则都设成 error,结果每次跑 CLI 出来几十条,看都看不过来,最后干脆不看了。后来按这个策略重新分配,error 控制在个位数,反而每条都会认真处理。
5. 实操全流程:从生成代码到校验通过
5.1 用 codex cli 生成初版代码
这一节我完整走一遍流程,你可以跟着复现。假设我要做一个用户资料卡片组件,我先用 codex cli 生成初版。
在终端里进入项目目录,敲codex进入交互模式,然后输入需求描述。这里有个技巧:描述里要带上你的设计约束,虽然 impeccable 后面会校验,但你在生成阶段就把约束告诉 AI,能减少后面的返工量。比如我会这样写:
生成一个用户资料卡片组件,使用 React 和 Tailwind CSS。 要求:圆角使用 12px,内边距使用 24px,卡片阴影使用轻微阴影, 头像使用全圆角,姓名使用 18px 字号加粗,职位描述使用 14px 灰色。codex cli 会吐出一段代码。我实测下来,带上这些具体数值之后,生成结果的合规率能从大概六成提升到八成以上。剩下的两成,就交给 impeccable 来抓。
5.2 跑第一遍 CLI 校验并读懂报告
代码落地之后,跑:
npx impeccable check src/components/UserCard.tsx输出大概长这样:
src/components/UserCard.tsx 12:5 error 间距值 20px 不在 tokens 列表中 spacing/no-arbitrary-value 18:3 warn 圆角值 10px 接近 token 12px,建议统一 radius/prefer-token 24:7 info 颜色 #6b7280 可替换为 token gray-500 colors/prefer-token 3 problems (1 error, 1 warning, 1 info)读这份报告的关键是看行号和规则名。行号告诉你问题在哪,规则名告诉你违反了哪条规则。规则名是分类/具体规则的格式,前面是分类,后面是具体规则,方便你按分类批量处理。
第一遍跑出来有 error 是正常的,别慌。我第一跑的时候一个组件出来七八条,处理完也就十分钟的事。
5.3 逐条修复与二次校验
针对上面三条问题,我逐个处理。
第一条,间距 20px 不在列表里。查一下 tokens,最接近的是 16px 和 24px。这里要看设计意图:如果这个间距是卡片内部的元素间隔,用 16px 更紧凑;如果是卡片和外部元素的间隔,用 24px 更舒展。我判断是内部间隔,改成 16px。
第二条,圆角 10px 接近 12px。这种就是典型的"手滑值",直接改成 12px。
第三条,颜色可以替换为 token。这个属于优化项,改不改都行,但既然报告出来了,顺手改掉,保持一致性。
改完再跑一遍:
npx impeccable check src/components/UserCard.tsx输出变成0 problems,通过。
5.4 浏览器扩展的实时校验体验
CLI 是批量的,扩展是实时的。启动本地开发服务器之后,打开页面,扩展会自动分析。我印象最深的一次是,CLI 报告里显示某个按钮"合规",但扩展在页面上给它标了个黄框。点开一看,原因是这个按钮的 hover 状态用了和默认状态不同的圆角值——CLI 只扫了静态代码,没扫伪类状态,扩展在运行时把 hover 也触发了,才抓到这个问题。
这个案例说明:CLI 和扩展不是重复的,是互补的。CLI 覆盖全,扩展覆盖深。两个都跑,才能把问题抓干净。
提示:扩展的实时分析会消耗一些性能,如果你在跑性能测试,建议先把它关掉,测完再开。
6. 常见问题与排查技巧实录
6.1 装了扩展但页面没有任何标注
这是问得最多的问题。排查顺序我整理成了一张表:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 图标角标为 0 | 未连接到本地服务 | 检查扩展配置里的地址和端口 |
| 角标有数字但页面无标注 | 标注层被页面样式覆盖 | 检查是否有 z-index 极高的元素遮挡 |
| 部分页面正常部分异常 | 页面用了 iframe | 扩展默认不注入 iframe,需手动开启 |
| 完全无反应 | 扩展未正确加载 | 重新加载扩展,看是否有报错 |
我遇到最多的是第一种。很多时候是因为本地开发服务器换了端口,扩展配置没跟着改。这个问题的隐蔽性在于,扩展不会弹窗提示你"连不上",它只是默默不工作。
6.2 CLI 扫描结果为空或明显偏少
扫描结果不对,八成是路径或者忽略配置的问题。先确认你传的路径对不对,npx impeccable check src/和npx impeccable check ./src/在某些 shell 下行为不一样。然后检查 ignore 配置,看是不是不小心把整个目录排除了。
还有一个容易被忽略的点:文件扩展名。impeccable 默认只扫.tsx、.jsx、.vue、.svelte这几种,如果你项目里用的是.ts写 JSX,需要在配置里显式加上。我就因为这个漏扫过一整个目录的组件。
6.3 规则误报怎么处理
误报是任何静态检查工具都躲不开的。impeccable 处理误报的方式有三种,按推荐程度排序:
第一种是行内忽略注释,在具体那一行上面加注释,只忽略这一行。这种方式最精确,适合个别情况。
第二种是配置里加例外,针对某条规则配置例外条件。比如某个第三方组件的颜色值确实不能改,就在配置里把那个文件排除在这条规则之外。
第三种是直接关掉规则。这个最不推荐,因为关掉之后同类问题都抓不到了。我一般只在确认这条规则对我的项目完全不适用时才关。
6.4 团队协作时的配置同步问题
团队里每个人本地跑出来的结果不一样,基本是配置版本不一致导致的。解决办法是把 impeccable 的配置文件和 CLI 版本都锁在项目里,通过 package.json 的 scripts 统一调用。比如:
{ "scripts": { "lint:design": "impeccable check src/" } }这样大家跑的都是npm run lint:design,用的是同一个版本同一份配置,结果自然一致。接入 CI 的时候也是调这个 script,本地和 CI 的行为完全对齐。
7. 把 impeccable 接入 CI 的实操细节
7.1 CI 配置的关键参数
接入 CI 的核心是让 error 级别的规则阻断合并。以常见的 CI 配置为例,关键是在流水线里加一步:
- name: Design Lint run: npm run lint:designimpeccable 在检测到 error 时会返回非零退出码,CI 会自动判定这一步失败。这里有个细节:warn 和 info 不会导致失败,所以你可以放心地把它们留在报告里,不会阻断流程。
7.2 增量校验与全量校验的取舍
全量校验每次跑整个代码库,慢,但覆盖全。增量校验只跑改动的文件,快,但可能漏掉跨文件的关联问题。我的做法是:PR 阶段跑增量,合并到主分支后跑全量。这样既保证了开发体验,又保证了主分支的质量。
impeccable 支持通过参数指定只校验改动的文件,具体用法是配合 git diff 拿到改动文件列表,再传给 CLI。这个在 CI 脚本里加几行就能实现。
7.3 报告的可读性优化
CI 里跑出来的报告如果太长,没人会看。我的优化经验是:只把 error 打到 CI 日志里,warn 和 info 输出到一个 artifact 文件。这样日志清爽,需要细看的时候再去下载 artifact。impeccable 支持通过参数控制输出级别,配置一下就行。
8. 我踩过的坑和几条实在建议
8.1 不要一上来就追求零 error
我刚开始用的时候,给自己定了个目标:所有组件零 error。结果第一天就卡住了,因为有些历史代码的间距值就是不在 tokens 里,改起来牵一发动全身。后来我调整了策略:新代码零 error,老代码逐步收敛。在配置里给老代码目录单独设一套宽松规则,新代码目录用严格规则。这样既能保证新代码质量,又不会因为历史包袱卡住进度。
8.2 tokens 的维护要有专人负责
tokens 是整套体系的地基,如果谁都能往里加值,很快就退化成一个大杂烩。我的建议是:tokens 的增删改要有明确的流程,比如需要设计负责人确认。这不是官僚,是因为 tokens 一旦失控,整个约束层的价值就没了。我见过一个项目,tokens 里的间距值有二十多个,从 2px 到 100px 几乎每个整数都有,那这个约束层等于没有。
8.3 扩展和 CLI 的规则要定期对齐
扩展和 CLI 用的是同一份配置,但它们的检测能力不完全一样。我建议每隔一段时间,拿同一个页面分别用扩展和 CLI 跑一遍,对比结果。如果发现差异很大,说明有一方的规则没跟上,需要检查配置。这个习惯帮我抓到过好几次配置漂移的问题。
8.4 把 impeccable 当成对话对象而不是裁判
最后说个心态上的事。impeccable 报出来的问题,不是每条都必须改。它是个工具,不是法官。有些规则在你的项目语境下就是不适用,那就大方地忽略掉。我现在的做法是:每条被忽略的规则,都在配置里写一行注释说明为什么忽略。这样过几个月回头看,还能想起来当时的判断依据,不会稀里糊涂地把规则越关越多。
这套工作流我用了大概两个月,最大的感受是:AI 生成前端代码的效率确实高,但效率的瓶颈从来不在生成,而在生成之后的收敛。impeccable 把收敛这件事从"靠人眼盯"变成了"靠规则卡",省下来的不只是时间,还有反复沟通的心力。如果你也在被 AI 生成的 UI 代码折磨,不妨从配一份 tokens 开始试试,哪怕先不接 CI,光是本地跑一跑,你就能感觉到区别。