行业资讯
📅 2026/9/9 19:03:51
Impeccable 设计系统 extract 流程实战:把重复 UI 提炼为可复用的组件与设计令牌
Impeccable 设计系统 extract 流程实战把重复 UI 提炼为可复用的组件与设计令牌【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccableImpeccable 是一套面向 AI 编程助手Cursor、Claude Code、Gemini CLI、Codex CLI 等的设计语言与技能包其extract命令专门解决一个问题当代码库中反复出现雷同的按钮、卡片、配色与间距而各处实现却不一致时如何系统化地把它们抽取、统一、收敛进一个可持续复用的设计系统。本文以 skill/reference/extract.md它在各 harness 下的分发副本位于 .qoder/skills/impeccable/reference/extract.md、plugin/skills/等目录为主线结合仓库内真实的设计系统产物DESIGN.md令牌规范与.impeccable/design.jsonsidecar完整讲解从发现设计系统到迁移与文档化的六步流程、判断标准与反模式清单让你能在真实项目中把三处重复的相似 UI变成一处高质量共享实现。一、extract 在 Impeccable 命令体系中的定位Impeccable 的技能入口 skill/SKILL.src.md 将全部命令划分为 Build / Evaluate / Refine / Enhance / Fix / Iterate 等类别。其中extract属于Build类别命令行为extract [target]在 skill/scripts/command-metadata.json 中它的元数据描述是Pull reusable patterns, components, and design tokens into the design system. Identifies repeated patterns and consolidates them. Use when you have drift across the codebase and want to bring things back to a consistent system.换句话说extract的触发时机是代码库出现设计漂移drift同一个概念如按钮、错误态、表单行在多个文件里有多种实现而其中没有任何一个被确立为共享版本。它与document命令自动从代码生成DESIGN.md互补document负责把现状碳化carbonize成规范文件extract负责把重复的现状收敛为系统资产——前者回答我们现在是什么后者回答我们应该复用什么。extract 流程的目标一句话即可概括Identify reusable patterns, components, and design tokens, then extract and consolidate them into the design system for systematic reuse.翻译成可执行的动作是识别可复用的模式、组件与设计令牌 → 抽取 → 收敛进设计系统 → 系统化复用。二、Step 1先发现设计系统而不是凭空新建流程的第一步是勘察既有的设计系统、组件库或共享 UI 目录而不是立刻动手抽取。需要理解的层面包括组件组织方式组件放在哪个目录、按什么粒度拆分命名约定组件名、CSS 类名、文件名遵循什么规则设计令牌结构颜色、字体、间距等是否已存在变量/令牌体系导入导出约定共享模块如何被消费import路径、barrel 文件等。该步骤带有一条CRITICAL 约束原文强调If no design system exists, do not create one yet. Ask the user directly to clarify what you cannot infer. Understand the preferred location and structure first.翻译如果项目根本不存在设计系统不要顺手新建一个。应该先向用户询问你无法推断出的信息——期望的目录位置与结构偏好。这与仓库 PRODUCT.md 记录的产品原则一致源改动应落在skill/、cli/、extension/等受控位置任何系统级资产都要先有归属地否则抽取出的共享组件只会制造第二个分叉点。实操提示如果项目没有任何 token、组件目录与共享样式文件extract 不是正确的切入点应回到document的 seed 模式或直接与用户确认目标结构后再继续。三、Step 2识别可抽取的模式与信号在目标区域内寻找可抽取的机会。参考文档给出了六大信号signal全部围绕同一意图的重复信号具体形态抽取对象重复组件Repeated components按钮、卡片、输入框等相似 UI 模式出现3 次以上可复用组件硬编码值Hard-coded values颜色、间距、字号、阴影散落在各处设计令牌不一致变体Inconsistent variations同一概念存在多种实现如 hover 效果三处三种写法统一变体组合模式Composition patterns重复出现的布局/交互组合表单行、工具栏分组、空状态模式文档或组合组件字体样式Type styles反复出现的 font-size weight line-height 组合排版令牌 / 字号角色动画模式Animation patterns重复的 easing、duration、keyframes 组合motion 令牌 / 动画预设3.1 价值评估三次法则与意图相同门槛文档给出明确的取舍标准这是整个 extract 流程最核心的判断only extract things used 3 times with the same intent. Premature abstraction is worse than duplication.两个条件缺一不可复用次数 ≥ 3只出现一两处、且短期内不会新增第三处的实现保持复制更划算。过早抽象比重复更糟——抽象引入间接层、props 面与维护成本却收不回收益。意图相同两个看起来像、但服务不同目的的东西必须分开详见NEVER清单例如两个样式相同的按钮一个提交订单、一个删除账户它们面向的风险与状态不同应当各自保留。这正是设计系统中相似 ≠ 相同的经典边界视觉复用是表象意图一致才是抽取的依据。四、Step 3制定系统化的抽取计划在动手写共享组件之前先产出一份计划文档要求覆盖五件事要抽取的组件哪些 UI 元素升级为可复用组件要创建的令牌哪些硬编码值变成设计令牌要支持的变体每个组件未来需要哪些变体尺寸、强调级别、状态命名约定组件名、令牌名、prop 名必须匹配既有模式不能另起炉灶迁移路径如何重构既有使用点让它们消费新的共享版本。计划阶段同时带有一条IMPORTANT约束Design systems grow incrementally. Extract what is clearly reusable now, not everything that might someday be reusable.设计系统是增量生长的。只抽取现在明确可复用的资产而不是未来也许可复用的一切。这既是防过度设计也是防抽取一次、维护一整年。4.1 计划清单示例一个面向 React 组件库的抽取计划可以长这样示意结构实际以项目为准抽取计划草案 ├── 组件Button │ ├── 来源features/*/button*.{jsx,tsx}已出现 7 处意图均为触发主操作 │ ├── 变体primary / secondary / ghostsize: sm / md │ ├── 命名沿用现有 components/ui/ 下 PascalCase 约定 │ └── 迁移统一走 barrel 导出删除各 features 内私有实现 ├── 令牌--color-brand / --space-3 / --type-label │ ├── 来源grep 统计出的高频硬编码值 │ └── 组织primitive原始值→ semantic语义别名两层 └── 文档README 补充使用示例与何时使用说明五、Step 4抽取并充实Extract Enrich这是把旧实现升级为更好的共享实现的一步。文档强调的不是简单搬运而是在抽取的同时做增量增强组件Components清晰的 props API 合理的默认值为不同使用场景提供正确的变体内置可访问性ARIA、键盘导航、焦点管理附文档与使用示例。设计令牌Design tokens命名上分清primitive原始令牌与semantic语义令牌两层有正确的层级与组织文档说明每个令牌何时使用。模式Patterns说明何时使用该模式、给出代码示例、变体与组合方式。5.1 抽取的落点仓库里的令牌规范是什么样extract 收敛出的令牌最终会进入与 skill/reference/document.md 一致的DESIGN.md体系。该体系的机器可读层是 YAML frontmatter只接受五类顶层分组colors、typography、rounded、spacing、components。令牌引用使用{path.to.token}语法组件可以引用原始令牌原始令牌之间不能互相引用--- name: project title description: one-line tagline colors: primary: #b8422e neutral-bg: #faf7f2 # ...每个被抽取的颜色一项key 描述性 slug typography: display: fontFamily: Cormorant Garamond, Georgia, serif fontSize: clamp(2.5rem, 7vw, 4.5rem) fontWeight: 300 lineHeight: 1 rounded: sm: 4px md: 8px spacing: sm: 8px md: 16px components: button-primary: backgroundColor: {colors.primary} textColor: {colors.neutral-bg} rounded: {rounded.sm} padding: 16px 48px ---仓库中的真实产物demos/landing-demo/DESIGN.mdLumina 设计系统就是一个活的范例frontmatter 里colors用的是描述性 slugcream、cream-warm、ink、accent-deep而非blue-800typography按角色分display/headline/title/body/labelcomponents的变体用命名约定表达button-primary/button-ghost/nav-pill为并列键并统一通过{colors.ink}、{rounded.pill}引用原始令牌。这与 extract 的价值判断完全呼应令牌的 key 必须携带语义品牌墨色而不是携带色阶#800 的第 8 号只为那些确实被复用的值建令牌——为每个像素值都建令牌令牌系统本身就失去了意义。5.2 frontmatter 装不下的内容交给 sidecarDESIGN.md 的 frontmatter 是规范性normative的一层但组件级的阴影、动效、断点、完整 HTML/CSS 片段放不进去。document 流程会同步维护.impeccable/design.jsonsidecar用extensions承载每个颜色的tonalRamp8 级 OKLCH 明度梯度、shadows、motion、breakpoints以及自包含、可注入 shadow DOM 的组件 HTML/CSS。参考 demos/landing-demo/DESIGN.json{ schemaVersion: 2, extensions: { colorMeta: { cream: { role: neutral, displayName: Cream, canonical: oklch(96.5% 0.012 80), tonalRamp: [oklch(15% 0.012 80), ...] } }, shadows: [], motion: [], breakpoints: [{ name: container, value: 1180px }] }, components: [ { name: Primary Button, kind: button, refersTo: button-primary, html: a href\#\ class\ds-btn-primary\Start free trial/a, css: .ds-btn-primary { ... } } ] }sidecar 组件片段要求自包含、可直接 drop-inTailwind 类要展开为字面 CSS、图标内联为 SVG、必须带:hover/:focus-visible状态、类名加ds-前缀防冲突。extract 抽取出的组件若要以设计系统真实资产的面貌呈现例如被 live panel 渲染就需要达到这个自包含标准——这正是抽取并充实中更好的可复用版本在仓库体系里的具体定义。六、Step 5迁移Migrate——让所有使用点消费共享版本抽取完成不等于结束真正的价值在迁移后兑现。文档给出四步Find all instances找出所有实例全库搜索你刚抽取的模式Replace systematically系统化替换逐个把使用点切到共享版本Test thoroughly充分测试确保视觉与功能等价visual and functional parityDelete dead code删除死代码清掉旧的私有实现否则系统里永远存在两份真相。实际执行时Find all instances通常对应在目标目录内做一次覆盖式检索例如按抽取来源的特征搜索# 找出所有仍引用旧私有按钮实现的文件逐一核对迁移状态 rg -l className\btn|\.btn-card|style\{[^}]*#b8422e --type ts --type css迁移的验收标准是视觉与功能 parity迁移后截图对比无差异、交互行为一致测试通过后再删除死代码。删除这一步经常被跳过而跳过它恰恰会让统一失效——旧实现留在原地下一个 AI/开发者仍可能复制它漂移会重新发生。七、Step 6文档化Document——让抽取结果可被发现、可被遵守迁移完成后更新设计系统文档参考文档给出的动作包括把新组件加入组件库清单记录令牌的用法与取值补充示例与使用准则guidelines更新 Storybook 或组件目录catalog。这一步回答 extract 的根本目的——systematic reuse系统化复用。没有文档的共享组件只是一个另一个副本使用方不知道它存在、不知道它该不该用、不知道变体怎么开。文档让被抽取的资产成为系统里可被检索、可被引用的唯一真相源。八、NEVER 清单extract 流程的七条红线参考文档用一组NEVER明确划出边界逐条展开如下#禁止行为背后的原因1抽取一次性、强上下文绑定的实现却不做泛化直接复用会把它本不该承担的上下文传染给所有消费者2创建过于泛化、空洞无用的组件全能的 props 面等于没有接口任何场景都不好改3抽取时不考虑既有设计系统约定新资产与旧体系命名/结构冲突等于制造新漂移4跳过规范的 TypeScript 类型或 prop 文档类型与文档是共享 API 的护栏缺失即退化回私有实现5为每个值都创建令牌令牌必须有语义意义否则令牌层变成另一份硬编码6抽取意图不同的东西两个看起来像但目的不同的按钮应当保持分离7隐含于 Step 1 CRITICAL没有设计系统就新建应先问清归属地而不是擅自发明结构第 6 条与第 3 条三次法则中的意图相同呼应最紧密视觉相似是抽取的必要条件不是充分条件。九、与仓库其它流程的衔接与document的关系extract 收敛出的令牌与组件产出物最终落进DESIGN.md体系令牌取值以 frontmatter 为唯一规范性来源prose 只描述哪里用、为何用不得用另一个十六进制值复述同一令牌。与live模式的关系.impeccable/design.json中的组件 HTML/CSS 会被 live 面板渲染成可交互的真实资产。抽取质量越高面板展示的就越接近产品真实基元demos/landing-demo/DESIGN.json中components数组即可视作 extract 输出的目标形态样例。与audit/ 反模式检测的关系extract 从源头减少同名不同实现类漂移而tests/fixtures/antipatterns/下的检测用例如各类 should-flag 场景则从检测侧兜底同类问题。运行入口在项目根目录通过/impeccable extract [target]触发技能总参考 skill/SKILL.src.md 的 Commands 表为extract [target]提供了参数提示与参考文档路由。十、总结extract 的正确打开方式把六步与四条纪律浓缩成一份执行清单先勘察Discover找不到既有设计系统时停下来问用户不擅自新建再确认信号Identify3 次 同一意图才算机会过早抽象比重复更糟后制定计划Plan组件/令牌/变体/命名/迁移路径五要素齐备只取当下明确可复用的抽取即增强Extract Enrichprops API、可访问性、primitive→semantic 两层令牌一个都不能省迁移到收敛Migrate全量替换 → 视觉/功能 parity 测试 → 删除死代码文档化收尾Document入库、写用法、更新目录让系统化复用真正成立。始终记住那句核心判断——Premature abstraction is worse than duplicationextract 不是把相似代码凑在一起的机械操作而是一项围绕意图一致 × 复用次数做的取舍艺术。判断对了抽取让代码库收敛、让 AI 后续产出自动对版判断错了你只是把三份重复换成了一份抽象的重复加两份文档。【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考