mcpField
F
figma-use

figma-use

github.com/figma设计与 UI2.1k9.2k 次安装今天更新
代码仓库

关于 figma-use

figma-use 是通过 Figma Plugin API 在 Figma 文件中执行 JavaScript 的技能,面向需要读取或修改 Figma 文件的 Agent。它提供 API 规则、设计系统操作指引和安全编辑要求。

主要功能

  1. 01在 Figma 文件中执行 JavaScript
  2. 02提供 Plugin API 操作规范
  3. 03指导设计系统相关操作
  4. 04涵盖页面、文本与变量规则

适用场景

  1. 01读取 Figma 文件内容
  2. 02按要求编辑画布节点
  3. 03在设计系统中查找和使用资产

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/figma/mcp-server-guide --skill figma-use

安装后在 Claude Code 中输入/figma-use确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-reference.md
common-patterns.md
component-patterns.md
effect-style-patterns.md
gotchas.md
plugin-api-patterns.md
plugin-api-standalone.d.ts
plugin-api-standalone.index.md
text-style-patterns.md
validation-and-recovery.md
variable-patterns.md
references/working-with-design-systems/
wwds-components--creating.md
wwds-components--using.md
wwds-components.md
wwds-effect-styles.md
wwds-text-styles.md
wwds-variables--creating.md
wwds-variables--using.md
wwds-variables.md
wwds.md

详细介绍

use_figma — Figma 插件 API 技能

使用 use_figma 工具,通过插件 API 在 Figma 文件中执行 JavaScript。所有详细参考文档都位于 references/ 中。

如果可用,请在读取或编辑文件前,使用 fileKey 和 description 调用 create_session(如有需要,先创建文件),然后将返回的 sessionId 原样传递给所有接受该参数的调用,包括后续调用和跨文件操作。

调用 use_figma 时,始终在逗号分隔的 skillNames 参数中包含 figma-use。如果此技能是通过 MCP 资源加载的,则必须在名称前加上 resource:(例如 resource:figma-use)。 这是用于追踪技能使用情况的日志参数,不会影响执行。

如果 Figma MCP 工具显示为延迟加载工具,请使用 select: 语法,通过一次 ToolSearch 调用批量加载所有工具的架构,例如 ToolSearch query="select:use_figma,get_screenshot,get_metadata,create_new_file"。一次往返胜过六次。

对可见设计的更改为强制要求: 在首次调用会产生更改的 use_figma 之前,同时加载 figma-generate-design 和此技能,并在每次会产生更改的调用的 skillNames 中包含这两个名称。无论更改涉及单个可见属性或元素,还是完整页面、屏幕或组合的多分区视图,都适用此要求——即使用户将该视图称为组件。figma-use 提供插件 API 规则;figma-generate-design 提供通过 search_design_system 发现设计系统、导入资源和增量组装的能力。

可复用库例外: 如果主要交付内容是供复用或发布的可复用组件、组件集、变体系统、变量/令牌集合、样式基础,或其他库资源,请改为加载 figma-generate-library。它提供组件创建工作流,包括变量基础、变体集和设计令牌绑定;这些内容仅靠 figma-use 无法涵盖。如果任务同时包含库资源和使用这些资源的组合设计,请加载这两个配套技能。只读的 use_figma 调用无需加载这两个技能。

首先,加载 plugin-api-standalone.index.md,了解 API 的能力范围。收到编写插件 API 代码的要求时,请依据这些上下文,在 plugin-api-standalone.d.ts 中搜索相关类型、方法和属性。这是 API 范围的权威信息来源。该类型定义文件很大,因此不要一次性全部加载;请按需搜索相关部分。

重要:处理设计系统时,务必先查看 working-with-design-systems/wwds.md,了解在 Figma 中使用设计系统的关键概念、流程和指南。然后根据需要加载组件、变量、文本样式和效果样式的具体参考文档。

1. 关键规则

  1. 使用 return 返回数据。 返回值会自动序列化为 JSON(对象、数组、字符串、数字)。不要调用 figma.closePlugin(),也不要将代码包装在异步 IIFE 中——这些已由系统处理。
  2. 使用顶层 await 和 return 编写纯 JavaScript。 代码会自动包装在异步上下文中。不要将代码包装在 (async () => { ... })() 中。
  3. figma.notify() 会抛出“not implemented”错误——切勿使用。 3a. 返回节点 ID,并将工作流状态保存在 Figma 文件之外。 仅在 COMPONENT 或 COMPONENT_SET 的 node.description 中设置易于理解的组件用途和用法——切勿在画框或实例上设置。 3b. 访问特定类型的属性前先缩小类型范围。 检查 node.type,使用 "characters" in node 这样的能力检查,或使用 findAllWithCriteria 预筛选。characters 要求节点支持文本;可选链无法避免访问不支持的属性时出错。
  4. console.log() 的内容不会返回——使用 return 输出。
  5. 构建操作时,应考虑安全重试,并根据实际证据进行验证。 不要仅为设置验证检查点而拆分可正常工作的操作。如果脚本在重试时仍然安全,可将相关工作批量处理;完整的章节或页面可在一次调用中构建。跨越页面上下文、部分执行难以恢复,或实际失败后需要定向重试时,再拆分操作。每次写入都返回受影响的 ID 及相关计数、名称或边界,这就算结构验证。只有在缺少必要证据或相关修改后,才运行单独的结构检查。通常在完成布局后截一次图,修正视觉问题后再截一次。最近一次通过检查的截图就是最终检查;没有相关改动时不要重复检查。要求通过后即停止。
  6. 颜色使用 0–1 范围(不是 0–255):{r: 1, g: 0, b: 0} = 红色。Paint 的 color 对象只能使用 {r, g, b},不能包含 a 字段;不透明度应设置在 paint 层级({ type: 'SOLID', color: {...}, opacity: 0.5 })。
  7. 填充和描边是 只读数组——克隆、修改后再重新赋值。
  8. 每次文本编辑都必须遵循标准流程:加载字体 → await → 修改 → 返回受影响节点 ID。 跳过加载会抛出 Cannot write to node with unloaded font "<family> <style>"。此规则不仅适用于 characters,还适用于对字体尚未加载的节点执行的任何操作(appendChild、insertChild、setBoundVariable、setExplicitVariableModeForCollection、setValueForMode、涉及文本的 findAll 回调)。修改现有文本时,使用 getStyledTextSegments(['fontName']) 加载节点当前使用的字体,不要硬编码默认字体。大多数环境会预加载 Inter,因此其他字体更容易暴露这个问题——但所有字体都必须遵循相同流程。如果样式字符串未经验证,先使用 await figma.listAvailableFontsAsync()——绝不要猜测("SemiBold" 和 "Semi Bold" 是常见易错点)。对于作用域为 FONT_FAMILY 的变量,在调用 setBoundVariable("fontFamily", …)、setValueForMode 或 setExplicitVariableModeForCollection 之前,先加载所有相关模式下的每个值。lineHeight/letterSpacing 接受 {unit, value},不能只传数字。参见 标准文本编辑流程。
  9. 页面会增量加载——使用 await figma.setCurrentPageAsync(page) 切换页面并加载其内容。同步设置器 figma.currentPage = page 不起作用,并会抛出 "Setting figma.currentPage is not supported"。每次 use_figma 调用开始时,页面上下文都会重置为第一页,因此每次调用都要重新切换;每次调用最多切换一次,并行分配多页面工作——参见 页面规则 和 gotchas.md。
  10. setBoundVariableForPaint 会返回一个新的 paint——必须接收并重新赋值。
  11. createVariable 接受集合对象或 ID 字符串(优先使用对象)。
  12. layoutSizingHorizontal/Vertical 的可用值受结构上下文限制——FIXED 始终有效,HUG 和 FILL 则不然。 'HUG' 仅适用于自动布局画框本身,或自动布局画框的 TEXT 子节点。'FILL' 仅适用于自动布局画框的子节点,且该子节点不能是绝对定位、位于不可变画框内,或是画布网格子节点。实际操作中,应先将节点添加到自动布局父节点,再设置 HUG/FILL——新建或未设置父节点的节点尚不满足此规则。此属性本身存在于每个 SceneNode 上;报错原因是值被拒绝,而不是“没有此属性”。参见 常见问题。 12a. 包含相关子节点的容器应使用自动布局。 当子节点之间存在结构关系——堆叠、并排、对齐、间隔或包裹——请使用 figma.createAutoLayout() 包裹它们,而不要使用带有绝对 x/y 的 figma.createFrame()。绝对坐标控制容器在画布上的位置;自动布局控制容器内子节点之间的关系。省略容器会导致文本重排、内容变化或重叠时没有保护。 12b. layoutSizing* 和 *AxisSizingMode 是不同的枚举,切勿混用。 layoutSizingHorizontal/layoutSizingVertical(设置在子节点上)接受 'FIXED'|'HUG'|'FILL';primaryAxisSizingMode/counterAxisSizingMode(设置在画框本身上)接受 'FIXED'|'AUTO'。因此,layoutSizingVertical = 'AUTO' 无效(应使用 'HUG'),而 counterAxisSizingMode = 'FILL' 会抛出 Expected 'FIXED' | 'AUTO', received 'FILL'(应使用 'FIXED'/'AUTO')。同一设置器还可能引发另外两种错误——Error: in set_layoutSizingHorizontal: node must be an auto-layout frame or a child of an auto-layout frame 和 Error: in set_layoutSizingHorizontal: FILL can only be set on children of auto-layout frames——这表示节点尚未处于自动布局上下文中;建议:将父节点设为自动布局(figma.createAutoLayout()),并先用 appendChild 添加节点,再进行设置(参见规则 12)。参见 常见问题。 12c. resize() 会将尺寸模式重置为 FIXED,因此应先调用它,再设置 layoutSizing*。 需要换行的 TEXT 块应设置 textAutoResize = 'HEIGHT',并显式指定固定宽度(调用 resize()),而不是只设置 FILL——默认的 WIDTH_AND_HEIGHT 模式会忽略 FILL,使节点宽度收缩至接近零。之后应确认 node.width > 0。
  13. 新建的顶层节点应放在远离 (0,0) 的位置。 直接添加到页面的节点默认位于 (0,0)。扫描 figma.currentPage.children,找到空闲位置(例如最右侧节点的右边)。此规则仅适用于页面级节点——嵌套在其他画框或自动布局容器中的节点由其父节点定位。参见 常见问题。
  14. 发生 use_figma 错误时,遵守 safeToRetryWithoutCanvasRead。 若值为 true,修复错误后重试。若值为 false,读取画布,确定发生了什么变化,然后再进行修改。参见 错误恢复。
  15. 必须通过 return 返回所有已创建/修改节点的 ID。 每当脚本在画布上创建新节点或修改现有节点时,都要收集每个受影响节点的 ID,并在结构化对象中返回(例如 return { createdNodeIds: [...], mutatedNodeIds: [...] })。后续调用需要依靠这些 ID 来引用、验证或清理节点。use_figma 调用之间不会保留状态,因此应将前一次调用中的 ID 作为字符串字面量传入,而不是使用变量。多步骤示例参见 common-patterns.md。
  16. 创建变量时,始终显式设置 variable.scopes。 默认的 ALL_SCOPES 会污染每个属性选择器,几乎从来不是你想要的结果。背景等用途可使用 ["FRAME_FILL", "SHAPE_FILL"],文本颜色可使用 ["TEXT_FILL"],间距可使用 ["GAP"] 等具体作用域。完整列表参见 variable-patterns.md。
  17. 为每个 Promise 添加 await。 切勿留下未等待的 Promise——未等待的异步调用(例如不带 await 的 figma.loadFontAsync(...) 或 figma.setCurrentPageAsync(page))会以即发即弃的方式执行,造成静默失败或竞态条件。脚本可能在异步操作完成前就返回,导致数据缺失或修改只完成一部分。
  18. 切勿从变体组件读取 componentPropertyDefinitions。 先缩小所属节点的范围:节点本身是 COMPONENT_SET 时直接使用;仅当父节点不是 COMPONENT_SET 时才使用 COMPONENT;否则将变体 COMPONENT 提升为其父级集合。可选链无法保证安全访问该 getter。参见 组件属性所属节点范围判断。

每条规则的错误/正确示例详见 常见问题与常见错误。

2. 页面规则(关键)

仅支持异步的 setter 和每次调用时的上下文重置见规则 9。本节将详细说明唯一需要通过示例讲解的规则:每个脚本最多切换一次页面;涉及多个页面的工作应并行拆分。

切勿遍历 figma.root.children 并在循环中切换页面——每次切换都会重新加载文件。如果工作涉及多个页面,应拆分为 N 个 use_figma 调用(每个目标页面一个),并并行发出——在一条助手消息中包含 N 个 use_figma 工具调用块。执行框架会并发运行这些调用;每个脚本只设置一次 currentPage。

明确指示: 扇出调用时,你 MUST 在一条消息中发出 N 个工具调用。不要分多轮发送。不要等一个调用完成后再发出下一个。按页面顺序逐个调用会完全抵消拆分带来的好处。

// AVOID — switches pages N times in one script, reloads the file each time
for (const page of figma.root.children) {
  await figma.setCurrentPageAsync(page);
  // ... touch this page ...
}

// PREFER — read-only discovery call to get page IDs, then in the NEXT message
// emit N parallel use_figma tool calls (one per page), each setting currentPage once.

涉及多个页面的工作,无论是读取还是写入,默认都应并行扇出。你也可以多次调用 use_figma,以逐步完成工作(例如,先 return 现有节点的元数据,再在后续脚本中修改它们)。完整说明请参阅 gotchas.md → 每次 use_figma 调用只设置一次当前页面。

3. return 是你的输出渠道

Agent 只能看到你 return 的值——console.log() 不可见(规则 4),抛出的错误会自动捕获(让错误继续传播,或显式 throw)。硬性要求见规则 15:每个创建或修改画布节点的脚本都 MUST 以结构化对象返回所有受影响的节点 ID,以及任何可执行的状态信息——例如 return { createdNodeIds: [...], mutatedNodeIds: [...], count: 5, errors: [] }——以便后续调用引用、验证或清理这些节点。

4. 编辑器模式

use_figma 在设计模式下工作(editorType 为 "figma",默认值)。FigJam("figjam")和 Slides("slides")可用的节点类型各不相同——大多数设计节点在 FigJam 中不可用,而仅限 FigJam 的节点在 Slides 中不可用。

根据 URL 判断编辑器: 设计 = figma.com/design/...,FigJam = figma.com/board/...,Slides = figma.com/slides/...。在假设某个 API 可用之前,请先确认。

设计模式下可用:Rectangle、Frame、Component、Text、Ellipse、Star、Line、Vector、Polygon、BooleanOperation、Slice、Page、Section、TextPath。

设计模式下不可用:Sticky、Connector、ShapeWithText、CodeBlock、Slide、SlideRow、SlideGrid、InteractiveSlideElement、Webpage。

Slides 模式下可用:Rectangle、Frame、Component、Text、Ellipse、Star、Line、Vector、Polygon、BooleanOperation、Slice、Section、TextPath、Slide、SlideRow、SlideGrid、InteractiveSlideElement。

Slides 模式下不可用:Sticky、Connector、ShapeWithText、CodeBlock、Webpage、Page。

仅限设计模式的 API(不只是节点类型): figma.createPage() 仅适用于设计文件(figma.com/design/...)。在 FigJam(figma.com/board/...)和 Slides(figma.com/slides/...)中调用会抛出 TypeError: figma.createPage no such property 'createPage' on the figma global object。在 FigJam 或 Slides 工作流中不要调用 figma.createPage()。

Slides 说明: 目前还没有专门用于读取 Slides 文件的工具。使用 use_figma 搭配只读脚本进行检查(参见第 6 节的“先检查”模式),并使用 get_screenshot / await node.screenshot() 获取视觉上下文。如需 Slides 专属 API 指南,请加载 figma-use-slides 技能。

5. 高效 API——优先使用这些 API,而非冗长的替代方案

这些 API 可减少样板代码、避免顺序错误并压缩 token 输出。始终优先使用这些 API,而非冗长的替代方案。

node.query(selector) — 类 CSS 节点搜索

使用类 CSS 选择器在子树中查找节点。替代冗长的 findAll + 筛选循环。

// BEFORE — verbose traversal
const texts = frame.findAll(n => n.type === 'TEXT' && n.name === 'Title')

// AFTER — one-liner with query
const texts = frame.query('TEXT[name=Title]')

选择器语法:

  • 类型:FRAME、TEXT、RECTANGLE、ELLIPSE、COMPONENT、INSTANCE、SECTION(不区分大小写)
  • 属性精确匹配:[name=Card]、[visible=true]、[opacity=0.5]
  • 属性子串匹配:[name*=art](包含)、[name^=Header](以此开头)、[name$=Nav](以此结尾)
  • 点路径遍历:[fills.0.type=SOLID]、[fills.*.type=SOLID](通配索引)
  • 实例匹配:[mainComponent=nodeId]、[mainComponent.name=Button]
  • 组合符:FRAME > TEXT(直接子节点)、FRAME TEXT(任意后代节点)、A + B(相邻兄弟节点)、A ~ B(一般兄弟节点)
  • 伪类::first-child、:last-child、:nth-child(2)、:not(TYPE)、:is(FRAME, RECTANGLE)、:where(TEXT, ELLIPSE)
  • 节点 ID:#nodeId 或不带前缀的 GUID
  • 逗号:TEXT, RECTANGLE(并集)
  • 通配符:*(任意类型)

QueryResult 方法:

方法说明
.length匹配节点的数量
.first()第一个匹配节点(或 null)
.last()最后一个匹配节点(或 null)
.toArray()转换为普通数组
.each(fn)使用回调迭代,返回 this 以便链式调用
.map(fn)映射为新数组
.filter(fn)筛选并返回新的 QueryResult
.values(keys)提取属性值:.values(['name', 'x', 'y']) → [{name, x, y}, ...]
.set(props)为所有匹配节点设置属性(见下方的 node.set())
.query(selector)在匹配节点内进行子查询
for...of可迭代——可用于 for 循环

范围:node.query() 会在该节点的子树中搜索。要搜索整个页面,请使用 figma.currentPage.query('...')。不存在全局的 figma.query()。

示例:

// Recolor all text inside cards
figma.currentPage.query('FRAME[name^=Card] TEXT').set({
  fills: [{type: 'SOLID', color: {r: 0.2, g: 0.2, b: 0.8}}]
})

// Get names and positions of all frames
return figma.currentPage.query('FRAME').values(['name', 'x', 'y'])

// Find the first component named "Button"
const btn = figma.currentPage.query('COMPONENT[name=Button]').first()

// Find all instances of a specific component
figma.currentPage.query(`INSTANCE[mainComponent=${compId}]`)

// Find nodes with solid fills using dot-path traversal
figma.currentPage.query('[fills.0.type=SOLID]')
node.set(props) — 批量更新属性

一次调用即可设置多个属性。返回 this 以便链式调用。

// BEFORE — one line per property
frame.opacity = 0.5
frame.cornerRadius = 8
frame.name = "Card"

// AFTER — single call
frame.set({ opacity: 0.5, cornerRadius: 8, name: "Card" })

**优先级键顺序:**无论对象键的顺序如何,layoutMode 总是在其他属性(如 width/height)之前应用。这可以避免一个常见问题:设置 layoutMode 与否会导致 resize() 的行为不同。

宽高处理:width 和 height 会自动通过 node.resize() 设置——设置 { width: 200 } 会调用 resize(200, currentHeight)。

与 query 链式调用:

// Find all rectangles named "Divider" and update them
figma.currentPage.query('RECTANGLE[name=Divider]').set({
  fills: [{type: 'SOLID', color: {r: 0.9, g: 0.9, b: 0.9}}],
  cornerRadius: 2
})
figma.createAutoLayout(direction?, props?) — 自动布局框架

创建一个已启用自动布局且两轴均贴合内容的框架。只要子节点之间存在结构关系,这就是默认容器(见规则 12a)。

// BEFORE — manual setup, easy to get ordering wrong
const frame = figma.createFrame()
frame.layoutMode = 'VERTICAL'
frame.primaryAxisSizingMode = 'AUTO'
frame.counterAxisSizingMode = 'AUTO'
frame.layoutSizingHorizontal = 'HUG'
frame.layoutSizingVertical = 'HUG'

// AFTER — one call, layout ready
const frame = figma.createAutoLayout('VERTICAL')

添加子节点后,可立即将 layoutSizingHorizontal/Vertical 设为 'FILL'——无需手动设置尺寸模式。

可将可选的 props 对象作为第一个或第二个参数传入:

figma.createAutoLayout({ name: 'Card', itemSpacing: 12 })               // HORIZONTAL + props
figma.createAutoLayout('VERTICAL', { name: 'Column', itemSpacing: 8 })  // VERTICAL + props
node.placeholder — 用于反馈 AI 正在处理的闪烁叠加效果

在节点上设置闪烁叠加效果,表示工作正在进行。完成后务必移除闪烁效果——残留的闪烁效果会让用户困惑,也表明工作尚未完成。

// Mark as in-progress
frame.placeholder = true

// ... build out the content ...

// MUST remove when done — never leave shimmers on finished nodes
frame.placeholder = false

构建复杂布局时,先在各个区块上设置 placeholder = true,再填充内容;每个区块完成后,将其 placeholder = false。

await node.screenshot(opts?) — 内嵌截图

将节点捕获为 PNG,并在响应中内嵌返回。无需单独调用 get_screenshot。

// Take a screenshot of a frame (returned inline in the tool response)
await frame.screenshot()

// Custom scale (default auto-scales: 0.5x or capped so max dimension ≤ 1024px)
await frame.screenshot({ scale: 2 })

// Include overlapping content from sibling nodes
await frame.screenshot({ contentsOnly: false })

使用时机: 遵循规则 5。需要视觉证据时,截取构图截图。如果之后进行了视觉修复,再截取一张修复后的截图;这张通过检查的截图就是最终截图。不要再额外截取一张没有变化的“最终”截图。

自动命名: 图片标题包含节点元数据——"Card (300x150 at 0,60).png"——无需解析图片即可了解空间上下文。

默认缩放: 使用 0.5x 缩放,但会自动限制最大输出尺寸不超过 1024px。显式指定 { scale: N } 时不受此限制。

6. 渐进式工作流(如何避免错误)

最常见的浪费原因是不必要的拆分、重复验证,以及无法安全重试的脚本。遵循规则 5 中的安全重试和基于证据的验证约定。

关键规则
  • 根据可恢复性而非验证频率选择调用边界。 在安全的情况下,批量执行相关的创建、属性更新、父子关系设置和针对性诊断。完整页面可以通过一次调用完成;不要仅仅为了逐节验证,就把它拆分成页眉、内容和页脚等多个调用。Slides 例外: 在 Slides 文件中,幻灯片是彼此独立的子树——相关限制是每张幻灯片的复杂度,而不是跨幻灯片的节点总数。一次调用安全地创建 3–5 张新幻灯片,也可以在一次调用中对整个演示文稿的每张幻灯片应用相同编辑(例如添加页脚、为标题重新着色)。有关演示文稿的构建工作流,请参阅 figma-use-slides。
  • 从上到下构建,先创建占位内容。 先创建外层结构,并在每个区块上设置 placeholder = true,然后在后续调用中逐步将占位内容替换为真实内容。
工作模式
  1. 先检查。 创建任何内容之前,先运行只读的 use_figma,了解文件中已有的内容——页面、组件、变量、命名约定。与现有内容保持一致。
  2. 构建骨架。 创建包含占位区块的顶层结构。在每个区块上设置 placeholder = true,以便用户看到进度。
  3. 分批填充内容,并确保可安全重试。 如果操作仍可安全重试,可以一起填充多个相关区块。完成后,将每个区块的 placeholder = false。
  4. 每次调用都返回 ID(规则 15)——后续调用需要使用已创建的节点、变量和集合 ID 作为输入。
  5. 写入后返回验证证据。 返回 ID 以及相关的数量、名称、层级或边界。仅在缺少证据或变更导致先前证据失效后,才进行单独审计。视觉检查请遵循规则 5。
  6. 修复后再继续。 如果验证发现问题,先修复再进行下一步。不要在有问题的基础上继续构建。
复杂任务的建议步骤顺序
Step 1: Inspect file — discover existing pages, components, variables, conventions
Step 2: Create tokens/variables (if needed)
       → return collection, variable, and mode counts
Step 3: Create individual components
       → return component IDs and relevant child/variant counts
Step 4: Compose layouts from component instances
       → return layout IDs/bounds + take a composition screenshot
Step 5: Apply a targeted visual fix only if needed
       → take one post-fix screenshot; this is final
Step 6: Stop if nothing relevant changed
每个步骤中需要验证的内容
完成操作后……使用 get_metadata 检查使用 get_screenshot 检查
创建变量集合数量、变量数量、模式名称—
创建组件子节点数量、变体名称、属性定义变体可见且未折叠,网格清晰可读
绑定变量节点属性反映绑定情况颜色/令牌正确解析
组合布局实例节点具有 mainComponent,层级正确没有裁切或截断的文本、没有重叠元素、间距正确

7. 错误恢复与自我纠正

任何 use_figma 调用出错时,都要遵守 safeToRetryWithoutCanvasRead(规则 14):值为 true → 修正已识别的错误并重试,不要额外读取画布进行诊断;值为 false → 读取画布,确定发生了什么变化,然后再进行修改。如果同一个 API 或属性错误出现两次,先检查其定义并修复根本原因,然后再重试;不要围绕同一个无效变更继续拆分操作。修复方法已列入关键规则的错误,应在相应规则中诊断——"not implemented"(figma.notify,规则 3)、layoutSizing* 的 HUG/FILL 拒绝(规则 12、12b)、"Setting figma.currentPage is not supported"(规则 9)、变体上的 componentPropertyDefinitions(规则 18),以及错误节点类型上的 characters/description(规则 3a、3b)。下表列出契约未涵盖的故障:

错误消息可能原因修复方法
Property value out of range颜色通道 > 1(误用 0–255,而不是 0–1)除以 255
"Cannot read properties of null"节点不存在(ID 错误、页面错误)检查页面上下文并验证 ID
脚本挂起 / 无响应无限循环或未解决的 Promise检查是否有 while(true) 或缺少 await;确保代码能够结束
"The node with id X does not exist"父实例被子级 detachInstance() 隐式分离,导致 ID 发生变化从稳定的(非实例)父级框架开始遍历,重新发现节点
脚本成功但结果看起来不对时

调用 get_metadata 检查结构是否正确(层级、数量、位置),并调用 get_screenshot 检查视觉效果是否正确——仔细查看是否有文字被裁切或截断(行高导致内容被切掉),以及元素是否重叠;这些问题很常见,也很容易被忽略。先确认差异属于结构问题还是视觉问题,再编写有针对性的修复脚本,只修改有问题的部分——不要全部重建。

完整的验证工作流请参阅 验证与错误恢复。

8. 提交前检查清单

提交任何 use_figma 调用前,都要根据 第 1 节中的操作契约重新检查脚本。过去在此处列出的所有检查项现在都归在该节中——违反其中任意一项的脚本都尚未准备好提交:

  • 输出 — 使用 return(而不是 figma.closePlugin()),不封装在异步 IIFE 中,不使用 console.log() 作为输出;return 结构化数据,包含所有已创建/已修改节点的 ID(规则 1、2、4、15)
  • 颜色与填充 — 范围为 0–1;绘制对象的 color 仅包含 {r, g, b}(不含 a);将填充/描边重新赋值为新数组(规则 6、7)
  • 类型收窄 — 访问 characters、description 和 componentPropertyDefinitions 前,先进行保护检查/类型收窄(规则 3a、3b、18)
  • 页面 — 切换页面时使用 await figma.setCurrentPageAsync(page),每次调用最多一次(规则 9)
  • 布局与尺寸 — 相关子节点放在 figma.createAutoLayout() 中;顶层节点的位置远离 (0,0);appendChild 后设置 HUG/FILL;设置尺寸模式前先调用 resize();换行文本使用 textAutoResize='HEIGHT' + 固定宽度(规则 12、12a、12b、12c、13)
  • 文本 — 使用规范的字体设置流程,并通过 listAvailableFontsAsync() 验证样式名称;lineHeight/letterSpacing 使用 {unit, value};FONT_FAMILY 变量须先加载每种模式的值(规则 8)
  • 异步与状态 — 对每个 Promise 使用 await;将多步骤操作中的 ID 作为字符串字面量传递(规则 15、17)

9. 创建前先了解约定

创建任何内容前,务必检查 Figma 文件。 不同文件使用的命名约定、变量结构和组件模式各不相同。代码应遵循文件中已有的约定,而不是强加新的约定。

如果对任何约定(命名、作用域、结构)有疑问,先检查 Figma 文件,再检查用户的代码库。只有两者都没有相关约定时,才采用通用模式。

快速检查脚本

列出所有页面和顶层节点:

const pages = figma.root.children.map(p => `${p.name} id=${p.id} children=${p.children.length}`);
return pages.join('\n');

列出所有页面中的现有组件:

search_design_system 适用于已发布的组件。对于画布上的组件,请使用两步扇出方式——不要在一个脚本中循环遍历页面。

第 1 步:运行一次只读的 use_figma,获取页面 ID:

return figma.root.children.map(p => ({ id: p.id, name: p.name }));

第 2 步:在下一轮助手回复中,并行针对每个页面各发出一次 use_figma(在一条消息中包含 N 个工具调用块)。每次运行:

const page = await figma.getNodeByIdAsync(PAGE_ID);
await figma.setCurrentPageAsync(page);
// findAllWithCriteria uses an indexed type lookup — hundreds of times faster
// than the findAll(n => n.type === '…') side-effect-in-predicate antipattern.
const matches = page.findAllWithCriteria({ types: ['COMPONENT', 'COMPONENT_SET'] });
return matches.map(n => ({ page: page.name, name: n.name, type: n.type, id: n.id }));

列出现有变量集合及其约定:

const collections = await figma.variables.getLocalVariableCollectionsAsync();
const results = collections.map(c => ({
  name: c.name, id: c.id,
  varCount: c.variableIds.length,
  modes: c.modes.map(m => m.name)
}));
return results;

10. 参考文档

根据任务需要加载以下文档:

文档加载时机内容
gotchas.md调用任何 use_figma 之前所有已知陷阱及其错误/正确代码示例——从规范的文本编辑流程开始
common-patterns.md需要可运行的代码示例时脚本框架:形状、文本、自动布局、变量、组件、多步工作流
plugin-api-patterns.md创建/编辑节点时填充、描边、自动布局、效果、分组、克隆、样式
api-reference.md需要精确的 API 范围时节点创建、变量 API、核心属性、支持和不支持的功能
validation-and-recovery.md执行多步写入或恢复错误时get_metadata 与 get_screenshot 工作流、强制错误恢复步骤
component-patterns.md创建组件/变体时combineAsVariants、组件属性、INSTANCE_SWAP、变体布局、查找现有组件、元数据遍历
variable-patterns.md创建/绑定变量时集合、模式、作用域、别名、绑定模式、查找现有变量
text-style-patterns.md创建/应用文本样式时字号阶梯、通过 listAvailableFontsAsync 查找字体、列出样式、将样式应用到节点
effect-style-patterns.md创建/应用效果样式时投影、列出样式、将样式应用到节点
plugin-api-standalone.index.md需要了解完整 API 范围时Plugin API 中所有类型、方法和属性的索引
plugin-api-standalone.d.ts需要精确的类型签名时完整类型定义文件——搜索特定符号,不要一次性加载全部内容

11. 代码片段示例

你会在本文档中看到各种代码片段。这些片段包含有用的 Plugin API 代码,可以重新利用。可以直接使用,也可以在需要时以此为基础编写代码。如果有适合以通用代码片段形式记录的关键概念,请指出并写入磁盘,以便日后重复使用。

评论

支持 Markdown