设计稿模块化还原 Skill
为什么需要这个 skill
把复杂设计稿一次性翻译成代码,几乎必然出现还原度问题:组件不一致、间距漂移、视觉层级被压扁、响应式行为丢失。根本原因是上下文超载——模型一边追踪整张页面(每个节点、每个 token、每个断点),一边写代码,细节就掉了。
这个 skill 强制把规划和执行拆开:先把整张设计稿读一遍,建立共享词汇(设计 token + 组件树),再对照渲染图逐个模块还原,最后拼接。
什么时候使用
只要用户要把 Figma 或 Mastergo 的设计稿转成代码就用,尤其是以下场景:
- 页面有 3 个以上明显分区(顶栏、Hero、列表、底部等)
- 有重复组件(卡片、列表项、多种按钮)
- 之前一次性还原过效果不好
- 用户提到了具体的 token、断点或响应式行为
只是单个小组件("把这个按钮转成 React")不需要走全套流程,直接做即可。
前置条件:MCP 必须连上
开工前先确认设计 MCP 是否已连接。常见的工具名前缀:
mcp__figma__*或figma:*— Figma MCPmcp__mastergo__*或mastergo:*— Mastergo MCP
每个 MCP 通常会提供这几类工具:
- 节点获取类 — 返回 JSON,包含节点的 type、name、children、layout、fills 等
- 图像渲染类 — 返回节点的 PNG/SVG,可指定缩放(一般 1x 或 2x)
- 代码导出类(可选)— 部分 MCP 能直接吐 CSS 或 React 片段,作为参考输入而非最终产物
如果没有任何设计 MCP 连接,告诉用户需要先连,然后停下。不要试图用截图代替——结构化的节点数据正是这套流程能跑得动的关键,特别是间距、字体、颜色 token 都需要从中读取。
具体的工具调用范式参考 references/mcp-patterns.md。
四阶段工作流
阶段 1 — 全局规划
目标:产出一份 PLAN.md,列清楚页面的所有模块和设计 token,在写任何代码之前先有这份文档。
-
先把项目上下文问清楚(如果用户没主动说)。这一步问得越清楚,后面返工越少。最少要确认:
- 设计稿来源:顶层节点的 URL 或 ID
- 目标框架与版本:React 18 还是 19?Vue 2 还是 3 + Composition API?小程序原生还是 uni-app/Taro?
- TypeScript 还是 JavaScript
- 样式方案:Tailwind / CSS Modules / SCSS / styled-components / WXSS / 等
- 是否有现成项目:是从零搭还是嵌入到已有项目?(嵌入会大幅影响下面几条)
- 现有组件库(关键):项目是否已经在用 Element Plus / Vant / Ant Design / shadcn/ui / 内部组件库?如果有,原子组件优先 wrap 现有的,不要从零造。
- 现有 token / 主题系统:有没有已经定义的颜色和字号变量?有的话用现有命名,不要发明新的。
- 产物去处:artifact 里写个 demo / 写到现有项目某路径 / 小程序工程 pages/xxx/
- 响应式范围:单视口(移动端 375)/ 多视口 / 流式
- 是否要做交互态:hover、active、disabled、loading 是否在范围内?
- 设计稿基准宽度:375 / 750 / 1440 —— 这个直接决定 rpx 换算或缩放系数
把这些问题一次性问完(用列表,便于用户对着勾选),别一个个零散问。
-
把整页低分辨率渲染一次(0.5x 或 1x 即可)有个全局视感。如果整页超过 6000px 或 MCP 渲染失败,按上中下三段分别渲染再拼接看。
-
拉顶层节点的树,但只往下走 2~3 层,不要直接钻到叶子。这一步是看模块结构,不是看每段文字。
-
按
references/plan-template.md的结构写PLAN.md,必须包含:- 概览:所有第 1 步问到的项目上下文
- 设计 token:颜色(含 hex 和角色名)、字号阶梯、行高、字重、间距尺度、圆角尺度、阴影
- 模块清单:从上到下编号列出每个模块,附
node_id、简述、大致尺寸 - 复用现有的部分(如有):列出哪些组件直接用现有组件库的 X,不重新造
-
把这份 plan 拿给用户确认:"这个拆分对吗?要不要合并或拆开某些模块?现有组件库的映射对吗?"等用户点头再继续。
这一阶段一般 2~4 次 MCP 调用。即使设计稿"看起来很简单"也别跳过——这份 plan 同时也是避免重复造组件、避免和现有项目冲突的依据。
阶段 2 — 组件树梳理
目标:产出一份 COMPONENTS.md,把页面里所有可复用元素列出来、分类、定好构建顺序。
-
把阶段 1 的每个模块过一遍,列出看起来像可复用的视觉元素:按钮、徽标、头像、卡片、列表项、输入框、导航项、Tab。
-
合并同款。如果三个不同分区里都出现了同样的卡片布局,那它就是 1 个
Card组件,不是 3 个。 -
优先复用现有组件库。如果阶段 1 第 1 步确认了项目在用某个组件库(Element Plus、Vant、Ant Design、shadcn/ui、内部库等),对每一个识别出来的原子/复合组件先判断:
- 直接能用 → 在
COMPONENTS.md里标注"直接使用<el-button>",不进自建组件清单 - 样式不一致需要 wrap → 标注为"基于
<el-button>包一层BrandButton",建在自建组件里但实现是 wrap - 现有库没有 → 标注为"自建"
不要看到设计稿就动手新建——先想想现有库有没有。多余组件是后期维护的负担。
- 直接能用 → 在
-
找全状态和变体。设计稿里同一个组件的 hover/disabled/loading/激活态通常不在主页面节点下,而是在:
- 设计稿的某个独立 frame("组件库"或"states"区域)
- Figma 的 Component Variants
- Mastergo 的组件状态切换
主动去找一下。如果找到了,把所有变体一次性映射到 props(
variant、size、disabled、loading);如果没找到,问用户:"这些组件的 hover/disabled 等状态在设计稿里有定义吗?还是按通用约定即可?"
-
给每个条目分类:
- Token — 纯设计值(颜色、字号),归入
tokens.css或主题文件 - Primitive 原子组件 — 没有子组件的最小单元(Button、Badge、Icon、Avatar)
- Composite 复合组件 — 由原子组件组成(Card = Avatar + Text + Button)
- Layout/Module 模块 — 页面级分区,一般不跨页复用(HeroSection、PricingTable)
- Token — 纯设计值(颜色、字号),归入
-
按
references/component-tree.md的结构写COMPONENTS.md。每个条目:名字、类型、来源node_id、复用状态(直接用 / wrap / 自建)、简述、需要的 props/variants(含状态枚举)。 -
在文档底部明确写出构建顺序:token → primitive → composite → module。
页面较小时不必再次和用户确认,直接进入阶段 3。复杂页面建议先把组件树过一遍。
阶段 2.5 — 按目标框架补一份功课
阶段 2 写完 COMPONENTS.md、即将进入阶段 3 之前,根据 PLAN.md 里定好的目标框架,读一下 references/framework-notes.md 里对应的章节。每个框架都有自己的还原坑:
- 微信小程序 / uni-app / Taro — rpx 单位换算、安全区、原生组件层级、滚动容器约束、字体加载差异
- Flutter —
height是行高比值、Color含 alpha、Widget 组合 - SwiftUI —
lineSpacing是行间距而非行高、Dynamic Type 适配 - React Native —
flexDirection默认 column、阴影双端 API 不同 - Web 主流(React/Vue/Tailwind) — 默认场景,约束最少
特别提醒小程序场景:rpx、安全区、原生组件层级这几条 Phase 1 就要写进 PLAN.md 的"概览",不要等到 Phase 3 才发现。
阶段 3 — 逐模块还原
按阶段 2 定好的顺序构建。每一个单元(不论是 token、原子、复合还是模块)都走同一套循环:
-
拉数据 + 渲染参考图。这次可以拉到完整子树,并按 2x 渲染存成 PNG,之后做对比要用。
-
对照组件清单。看用到了哪些已有组件。如果中途发现新的可复用模式,停下,先把它加进
COMPONENTS.md,构建好,再回来。 -
写代码。引用
PLAN.md里的 token(已有 token 的颜色不要再写 hex 字面量),引用COMPONENTS.md里的组件(不要重新实现已有的)。 -
想办法对比。这一步在工程项目里有几个现实路径,按可行性优先选:
- A:直接渲染对比(最优)。代码本身就能直接预览(HTML/CSS、artifact 里的 React/Vue、纯 SwiftUI Preview),渲染出来截图和参考图并排。
- B:模块抽离到 artifact 验证。原项目跑不起来时(比如要还原到一个完整 Vue/Next 项目里),把当前模块的 HTML/CSS 抽出来写到 artifact 里独立渲染,看是否对得上。这是工程场景下最常用的降级。
- C:小程序/原生场景靠用户。小程序、Flutter、SwiftUI 这种没法直接渲染的,写完明确请用户截图:"请把开发者工具的预览截图贴给我,我对比设计稿。"不要自己脑补已经对得上。
- D:纯静态对比(最弱)。前三个都做不到时,把代码里的 CSS 值(颜色、间距、字号、行高)和参考图里能读到的对照看一遍,类似 lint。这个能抓 80% 的明显错误,但抓不到布局漂移。
不管走哪条路径,都要在交付时告诉用户走的是哪条——B 和 C 有"实际项目里可能有差异"的风险。
-
过 fidelity 检查清单。按
references/fidelity-checklist.md过一遍,把差异分两档:- 必修差异:颜色错、布局结构错、组件用错、字号差超过 2px、间距差超过 4px
- 可记录差异:字间距 0.5px 以内的微调、阴影颜色微差、边框透明度差异
必修的当下修。可记录的写到模块文件顶部的
// FIDELITY-NOTES:注释里,最后在阶段 4 的交付清单统一汇总——这样用户能看到所有未完美还原的点,自己决定是否进一步打磨。 -
修复后再比一次。差异不可接受就改,改完再 diff。不要带着"必修差异"进入下一个模块——它们会在后面累积放大。可记录差异可以带着走。
会话中断怎么办:如果对话太长被截断、或者用户中途要停一下明天接着做,PLAN.md + COMPONENTS.md + 当前已写完的代码就是完整状态。下一轮对话开始时让 Claude 重读这两份文档和已有代码,就能从断点继续,不用从头规划。
阶段 4 — 整体拼接
- 按
PLAN.md里的整体布局把所有模块拼起来。 - 渲染整页,对比阶段 1 留的整页参考图。
- 检查跨模块的一致性:同一个
Card在不同分区里看起来一致;模块之间的间距和设计稿一致;顶栏 sticky 行为符合设计意图。 - 如果阶段 1 定了响应式断点,逐个跑过去检查。
- 完整交付清单——给用户一份结构化的 handoff,包含:
- 新建文件清单:按 token / 原子 / 复合 / 模块 / 整页分组列出
- 复用现有组件的清单(如果阶段 1 标了现有组件库)
- 阶段 3 收集的"可记录差异"汇总:每条注明在哪个模块、什么差异、为什么没修。让用户决定是否继续打磨。
- 使用方式:如何把模块嵌进现有项目(import 路径、Provider 顺序、依赖的 token 文件路径)
- 跑通命令(如适用):
npm install、npm run dev、小程序开发者工具加载哪个目录 - 依赖说明:用到了哪些第三方包(lucide-react、dayjs、numeral 等),用户需要手动安装的列出来
- 主动决定的偏离:哪些地方你判断设计稿可能有问题、做了变通(比如行高 22.5 round 到 22)
- 未做的事情:动效、空状态、错误态、骨架屏、SSR、a11y——这些不在范围内的明确说
反模式(最容易翻车的几种)
- 觉得"设计稿简单"就跳过阶段 1 或 2 — 阶段 3 进行到一半时会发现同一个 Card 写了三种版本
- 从顶到底建模块(先做顶栏后做底部) — 顶部模块往往用到底部也会用的原子组件,应该先做原子,模块从依赖少的开始
- 不从 MCP 拉颜色,肉眼估 — 设计稿有精确的 hex 值,必须用真实值
- 把 MCP 的代码导出结果当最终产物 — 那只是一个起点,必须对照渲染图核对
- 明知道还原有问题还往下做 — 当下不修,后面会让整页崩盘
- 从静态截图盲猜动效和交互 — 这些一般在静态渲染里看不到。先问用户是否在范围内,需要做就请用户给规格
这个 skill 会产出哪些文件
一次完整流程跑完,用户项目里应该有:
PLAN.md— 阶段 1 的全局规划COMPONENTS.md— 阶段 2 的组件树- 一份 token 文件(CSS 变量 / 主题对象 / Tailwind 配置 — 看框架)
- 每个原子组件、每个复合组件各自一个文件
- 每个模块一个文件
- 拼好的整页
PLAN.md 和 COMPONENTS.md 留在项目里——后续做"把全站次级按钮颜色改一下"这种修改时,它们就是给未来的你(或未来的 Claude)看的导航地图。
参考文档
走到对应阶段再读,平时不预加载:
references/plan-template.md—PLAN.md的完整结构和填写示例references/component-tree.md—COMPONENTS.md的完整结构和填写示例references/fidelity-checklist.md— 每个模块完成后的核对清单references/mcp-patterns.md— Figma 和 Mastergo MCP 的常见工具调用范式,含未知 server 的探查方法references/framework-notes.md— 按目标框架的特殊处理(小程序、uni-app/Taro、Flutter、SwiftUI、React Native、Tailwind)
微信扫一扫