关于 figma-codegen
figma-codegen 是一项将 Figma 选区转换为项目代码的技能,面向需要让实现贴合现有代码库的开发者。它通过读取设计结构、组件和令牌映射来优先复用现有实现,并支持按设计差异增量同步。
主要功能
- 01读取 Figma 结构与设计令牌
- 02将设计组件映射到代码组件
- 03复用项目令牌和样式
- 04导出图像资源并匹配图标
- 05检测设计变更并增量更新代码
- 06记录已确认的组件与令牌映射
适用场景
- 01根据 Figma 选区实现界面组件
- 02将设计稿适配到现有项目组件
- 03设计更新后仅修改对应代码
- 04为重复使用的映射建立记录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ awdr74100/ figwright --skill figma-codegen安装后在 Claude Code 中输入/figma-codegen确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/assets-and-icons.mdgrounding.mdmotion.mdresponsive.mdstylesheets.mdverify.md详细介绍
figma-codegen
将 Figma 选区转换为代码,使其风格与项目其余部分一致:复用现有组件和设计令牌,只构建真正缺失的部分。基于实际设计信息的工具会承担大部分工作,因此你无需对着截图猜测。本文件是路由入口;详细内容位于 references/ 中——当某个步骤需要时,再加载对应参考文档。
适用场景
- 用户粘贴 Figma URL 或选区,并要求生成代码(“把这个写成代码”“构建这个组件”)。
- 用户希望扩展现有组件,使其与 Figma 画板一致。
同时打开多个 Figma 文件时
适用时,每个工具结果都会说明这一点,因此你无需预先检查:如果连接了两个或更多文件,且尚未指定要使用哪个文件,结果中就会包含一个 MORE THAN ONE FIGMA FILE IS OPEN 区块,并列出这些文件。之所以重要,是因为否则调用会使用用户上次操作的文件,而用户切换标签页时,这个文件也会随之改变——因此,任务可能会读取一个文件、写入另一个文件,却仍报告成功。
看到该提示时,先指定文件,再进行其他操作:list_files 会列出所有已连接的文件,use_file({ fileName }) 会为本次会话指定一个文件(如果两个打开的文件同名,则使用 use_file({ sessionId })——Figma 允许这种情况,x (Copy) 就是这样产生的)。之后的每次调用都会访问该文件,无论哪个文件处于前台,包括其标签页位于后台时。如果用户没有说明要使用哪个文件,请先询问,不要根据文件名猜测。
工作流
针对选区运行基于实际设计信息的工具,然后生成代码——以这些工具的结果为准,而不是渲染图像。
get_design_context(详情级别full,dedupeComponents: true)→ 获取结构树,其中的设计令牌已解析为名称(Primary/500、spacing/4),样式已去重到globalVars,且每个实例都包含mainComponent/componentProperties。这是布局和绑定的事实来源。保留dedupeComponents: true,不要对要构建的子树进行深度限制。 → 关于如何读取结构树、各节点保真度目录(效果、逐边框线、描边对齐、逐角圆角、混合、蒙版、渐变、图像适配、图案、Figma Draw 重复组/笔刷描边/路径文字、自动布局/网格、宽高比、滚动/粘性、堆叠与描边空间)、作为事实依据的 Dev Mode 注释,以及如何为大到无法通过单次调用处理的页面建立设计依据:references/grounding.md。component_map→ 每个 Figma 组件都会与一个本地代码组件关联,并附带status(high / medium / low / unmapped)、candidate.filePath和matchedProps。high/medium:复用该组件(从candidate.filePath导入),不要重新生成。 绝不要编造component_map未报告的组件名称。candidate.ambiguousWith(一个经过数量限制的{ name, filePath }列表):Figma 名称与两个或更多 代码组件的匹配度几乎相同,关联过程无法有把握地选出一个——这是一个需要核实的选项, 而非确定可复用的组件(类似于token_map的ambiguousWith)。导入前,先检查获胜的candidate与这些次选项中,哪个才适用于_当前_上下文(错误复用会造成不易察觉的视觉错误), 然后将确认的组件记录到映射文件中,以确保下次运行时结果明确。如果选择没有歧义,则不会出现此字段。- 将每个条目的
instances[].props(解析后的变体/布尔/文本值)传给复用组件——每个实例对应一个元素, 且各自拥有自己的 props。 candidate.unmatchedProps:组件没有对应 prop 的 Figma 轴(例如前置图标、required标志或激活状态)→ 将其列为组件扩展 TODO,绝不要用临时标记语言伪造。unmapped:按照项目风格新建。如果一个未映射组件会重复出现 (instanceCount > 1),则从其第一个实例的子树构建;如果该子树返回deduped/truncated,则对instances[0].nodeId调用一次get_design_context深入检查——不要凭直觉重建 重复组件。- 输出组件的自身定义(其 prop 类型,而不只是渲染它)时,对该组件/实例调用
get_component_api可获得完整的属性 API——包含每个 VARIANT 选项,以及每个 BOOLEAN/TEXT/INSTANCE_SWAP prop 及其默认值——因此 prop 范围有依据,而非根据碰巧看到的实例推断。 - 该 API 会命名 props;树则会命名每个 prop 所驱动的图层。COMPONENT 或 INSTANCE 内的子图层带有
componentPropertyReferences({ characters | visible | mainComponent: "PropName#1:2" })。将该图层连接到 prop,而不是连接到它 恰好渲染出的内容:characters: "Label#1:2"对应{props.label},而不是设计中的字面字符串;visible: "Show Badge#3:4"则会控制条件渲染。如果没有这一步,你输出的标记语言虽然正确,却会完全没有 props——每个实例都会被冻结为你看到的那个实例的状态。
token_map→ 每个 Figma 变量都会与一个项目令牌关联,并附带status+ref+matchedBy。 文档的共享填充样式(单色填充样式——变量出现前文件中的令牌机制)也以同样方式关联,并标记为source: 'style'。- mapped:引用
candidate.ref(bg-primary-500、var(--color-primary-500))——绝不要使用get_design_context解析出的原始 hex/px 值。若某个颜色通过matchedBy: ['name']匹配(值已发生偏移),则使用它,但要标记出不匹配。 candidate.ambiguousWith(多个项目令牌共享完全相同的值,且名称无法区分它们):这是一个有数量上限、需验证的候选项——根据上下文选择语义上正确的同类令牌(或保留该值并指出缺口),绝不要将其视为已确认复用。- 对于变量很少或没有变量的文档(大多数真实项目文件都如此),
get_design_context自带的projectTokens映射是备用方案:负载中任何与项目令牌值完全相同的原始颜色,都会在此处加上注释({ "#6266F0": { ref, name, matchedBy: ["value"] } })。硬编码 hex 之前,先查找它;若在语义上符合上下文,则输出ref。matchedBy: ["value"]表示这是不考虑名称、基于值相等得出的证据——只是有待验证的假设,并非已解析的绑定:带有candidates的条目会列出值相同的令牌,需根据含义从中选择;语义上错误的令牌比原始值更糟(应保留原始值并指出缺口),而已绑定的 Figma 变量始终优先于原始值匹配。 framework-builtin(项目实用工具框架内置的比例步长,例如 Tailwind 或 UnoCSS 中的spacing/4、line-height/7、weight/Bold):包含builtin: { scale, step }——组合使用实用工具(p-4/gap-4、leading-7、font-bold),不要使用任意值p-[16px]。这不是缺口。from(SCSS 变量):仅靠该引用无法解析。你编写的文件必须导入声明该变量的文件;而且from是相对于仓库根目录的路径,Sass 则相对于导入它的文件解析@use——因此要从你正在编写文件的位置重新解析:在src/components/card.scss中,from: src/styles/_tokens.scss应转换为@use '../styles/tokens' as *,绝不能原样使用相对于仓库根目录的路径。as *会让引用保持原样;也可以遵循项目自身的@use风格使用命名空间(@use '../styles/tokens'会将$color-primary-500转换为tokens.$color-primary-500)。未导入文件就输出引用会导致编译错误,不只是样式问题。unmapped:使用该值,但要指出缺口(并提出将其添加到令牌来源);不要悄悄硬编码。figmaModes({ Light: …, Dark: … },文件的主题轴位于themedCollections中):该令牌依赖主题——figmaValue仅代表默认模式,并非全部情况。已映射:输出candidate.ref,并确认项目令牌本身会随主题切换(.dark/[data-theme]/prefers-color-scheme/dark:方案);如果项目只定义了一个值,则将另一模式的值接入该机制,或指出主题缺口。未映射:默认模式作为基础值,其他模式通过项目的深色模式机制处理(dark:变体 /prefers-color-scheme)。通过不具备原生模式的方式编码的主题——成对集合或名称组(Color/Light/*+Color/Dark/*,这是受方案限制的变通方式)——也按同样方式处理。带有variableModes({ color: "Dark" })的节点是在该模式下绘制的:令牌名称相同,使用该模式的值。保留令牌引用,并将子树放在该模式对应的项目机制之下;同一元素的 Light 和 Dark 画面是一个组件在两种主题下的呈现。 →references/grounding.md。
- mapped:引用
- 导出 grounding 无法承载的资源——Logo、照片、图标没有像素,否则会渲染为灰色块。对于
IMAGE填充节点,使用save_image_fills(原始资源,而不是裁剪后重新渲染的版本);图标优先使用icon_map(复用精选的.svg);只有需要合成后的效果时才使用get_screenshot。 → 完整的资源/图标/svg/颜色契约工作流:references/assets-and-icons.md。
然后使用检测到的技术栈输出代码(技术栈信息会通过 component_map / token_map 返回;无需自行调用 analyze_project):组合复用的组件,封装未映射的部分,并应用颜色/间距/圆角/字体排版的 token 引用。
设计变更时保持代码同步
代码生成很少一次完成——设计会不断变化。为了让第二次处理成为增量编辑,而不是重新生成:
- 生成代码后,针对区块/组件的
nodeId执行design_diff,将其get_design_context保存为基线,存放在.figwright/snapshots/下。提交该文件后,团队成员即可共享基线;该工具不会操作 git。 - 需要重新同步时(“设计变了,更新组件”),再次对同一个
nodeId执行design_diff:它会返回逐节点、逐属性的差异——包含已添加 / 已移除 / 已更改节点及其解析后的值(填充、内边距、文本字符串、token 重新绑定等),每项都有易读的path(Card / Header / Title)。只编辑这些节点对应的代码;不要重新生成整个屏幕。像往常一样根据变更值进行 grounding(它是get_design_context的切片),然后使用update: true执行design_diff,将新设计设为基线。 - 使用你编写代码时相同的
nodeId单位来限定范围。no-changes表示自基线以来设计未变更——无需处理。 - Motion 除外。 快照是完整且去重后的
get_design_context,其中只包含 Motion 摘要(预设名称、动画字段名称、时间线长度)——因此,变化的关键帧时间、值或缓动,或预设的配置或属性,都可能返回no-changes;去重时被折叠的实例子节点则完全不包含摘要。要重新同步动画,请在根节点上重新运行get_motion_context,并与代码实现进行比较。
记录已验证的映射(让下一次运行复用,而不是重新猜测)
每次运行都会从头重新推导关联。你确认过的映射——例如复用了某个组件并验证渲染正确,或将有歧义的颜色解析为语义正确的令牌——值得记录下来,这样下一次运行就会将其视为事实依据,而不是重新猜测。有两个只追加、不覆盖的映射文件,每次关联都会读取它们,并将其视为最高优先级依据:
-
docs/figma-component-map.md— 行格式为| FigmaName | code/path |(或FigmaName -> path)。component_map随后会以source: 'map-file'、置信度为 1 的形式返回该组件。 -
docs/figma-token-map.md— 行格式为| FigmaName | ref |。token_map会以matchedBy: ['map-file']、置信度为 1 的形式返回该令牌。ref是你要输出的内容——工具类(bg-primary-500)、var(--color-primary-500),或不带修饰的令牌名称。 -
已记录的行会在所有后续运行中覆盖模糊关联——因此要记录经过验证的结果,而不是猜测。 门槛是你自己的验证步骤(§ 响应式与验证):只有在渲染结果并确认其与 Figma 节点匹配后,才记录你_验证过_的映射。错误的行不会显式报错——它会在之后每次生成时静默地将组件或令牌映射错误,直到有人发现,这比完全不记录更糟。如果你不确定,就不要记录;下一次运行重新猜测还可以补救,而记录了一个确信无疑但错误的映射则无法补救。
-
只记录关联结果不确定的映射——你确认过的
low/medium组件匹配、你构建的unmapped组件(记录其新文件),或返回ambiguousWith/matchedBy: ['value']/unmapped并由你根据含义解决的令牌。跳过已经是high的确定性匹配;它们能正确地重新推导,为它们添加行只会造成冗余。 -
这些文件是项目中会提交的文档——应像断言代码行正确那样对待每一行,而不是将其视为临时笔记。每行对应一个 Figma 名称 → 一个目标;保持内容便于审查。
-
保持文件内容有效。 当
component_map/token_map报告staleOverrides(记录的目标已无法解析——文件或令牌已重命名或删除)时,关联已退化为模糊结果;请将该行修正为新目标,或删除该行。
响应式与验证
- 默认采用响应式布局——根元素使用
w-full,绝不使用画板的固定宽度;根据文件中其他宽度的画框确定断点。→references/responsive.md。 - 完成前先进行视觉验证——使用项目的工具链进行渲染,在设计的视口尺寸下截图,与 Figma 节点进行差异比较,并从源头修复问题。
→
references/verify.md。
动效(动画)
对于每个实现的根节点,都调用一次 get_motion_context:它会盘点子树中的所有 Motion 来源(包括实例子节点),并说明哪些内容无法读取。只有当 coverage.status: "complete" 且没有节点时,才能确认没有动画——get_design_context 中的 motion 摘要只是提示,可以在去重和预算时忽略。使用项目自身的动画机制实现其返回的内容,按照参考文档中经测量得出的规则进行读取;对于未明确说明的内容(轨道如何组合、循环或触发),将其视为你的假设并予以说明,然后根据源文件验证结果。遗漏画框的动画属于保真度缺失,与遗漏阴影性质相同。
→ references/motion.md。
规则
- 每个区块都要依据设计信息,绝不能凭截图估值。 所有像素尺寸、颜色、字号、圆角和间距,都必须针对每个区块从
get_design_context获取。截图仅用于表达视觉意图;猜测“简单区块”的值是最严重的疏漏。如果页面过大,无法一次性获取完整设计信息,就按区块的nodeId限定范围——绝不能对整个页面设置深度上限,也绝不能重试超出限制的调用。 - 复用优于重新生成。 必须导入并使用
component_map中high/medium级别的候选项。 - 引用设计令牌,不要使用字面值。 输出映射变量的
ref;仅在unmapped缺项时使用原始值,并明确指出这些缺项,不要将其隐藏。 - 保留所有视觉属性,不能牺牲还原度。 效果、各边框及其
strokeAlign、各个角的圆角、混合模式、蒙版、渐变、图片scaleMode、图案平铺、重复组中的副本(repeatTransforms),以及自动布局/网格间距,都包含在上下文中——逐项转换(属性目录见references/grounding.md)。遗漏任何属性都是设计信息获取不到位,而非简化:重复组只绘制一次,就像一个有 12 个刻度的刻度盘只画了一个刻度。 - 导出视觉资源,不要伪造。 灰色方框或手动输入的文字标识都不合格。
- 匹配项目,而非套用固定风格。 遵循现有的导入风格、文件布局和命名方式。
- 完整写出类名;不要用
&拼接。 在&用于拼接的语言(SCSS / Sass / Less / Stylus / postcss-nested)中,.card { &__title {} }会编译为.card__title——这个名称只在编译后存在,因此标记中使用的类名不会出现在源码里;调整一条规则时,就得搜索__title这样的片段并逐一检查所有匹配项。应在顶层直接声明完整类名。profile.styling.classNaming(位于component_map/token_map中)会报告项目自身的惯例,以项目为准:ampersand→ 使用&__title;flat或未提供时 → 直接写出完整类名。 →references/stylesheets.md介绍了看似可行、实则无效的后代选择器陷阱,以及&适用的场景。 - 完成前先渲染并验证。(参见
references/verify.md。) - 绝不编写配置文件或向导提示词;所有信息都应从项目和工具推断得出。