跳转至

Figma 插件开发指南

基于官方文档和实践总结的 Figma 插件开发流程。

参考资料

文档 链接
插件开发主站 https://developers.figma.com/
Manifest 规范 https://www.figma.com/plugin-docs/manifest/
editorType 说明 https://www.figma.com/plugin-docs/setting-editor-type/
插件 API 参考 https://www.figma.com/plugin-docs/api/figma/
showUI 详细文档 https://developers.figma.com/docs/plugins/api/properties/figma-showui/
figma.ui API https://developers.figma.com/docs/plugins/api/figma-ui/
TextNode API https://developers.figma.com/docs/plugins/api/TextNode/

项目结构

Figma 插件至少需要三个文件:

my-plugin/
├── manifest.json    # 插件配置
├── code.ts          # 主逻辑(TypeScript 源码)
├── code.js          # 编译后的主逻辑(Figma 实际加载)
└── ui.html          # 插件 UI 弹窗(可选)

manifest.json 核心字段

{
  "name": "插件名称",           // 在菜单中显示的名称
  "id": "插件ID",               // Figma 分配的插件 ID
  "api": "1.0.0",              // API 版本
  "main": "code.js",           // 主逻辑入口文件(相对路径)
  "ui": "ui.html",             // UI 文件(可选)
  "editorType": ["figma"],     // 支持的编辑器类型
  "documentAccess": "dynamic-page"  // 新插件建议开启
}

editorType 可选值

含义
"figma" Figma 设计模式
"figjam" FigJam 白板模式
"dev" Dev Mode
"slides" Figma Slides
"buzz" Figma Buzz

注意:"figjam""dev" 不能同时使用。

其他常用可选字段

{
  "networkAccess": {
    "allowedDomains": ["none"],        // 或具体域名
    "devAllowedDomains": ["http://localhost:3000"]  // 开发环境域名
  },
  "capabilities": ["codegen", "inspect"],  // Dev Mode 能力
  "permissions": ["currentuser"]       // 需要用户数据的权限
}

TypeScript 编译配置

@figma/plugin-typings 包的 package.json"main": "",导致 TypeScript 的 types 编译选项无法自动解析。需要手动添加引用:

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "lib": ["ES2017"],
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["code.ts"]
}

code.ts 顶部必须添加三斜线引用:

/// <reference path="./node_modules/@figma/plugin-typings/index.d.ts" />

否则会报 Cannot find name 'figma' 错误。

package.json:

{
  "devDependencies": {
    "@figma/plugin-typings": "^1.100.0",
    "typescript": "^5.3.0"
  },
  "scripts": {
    "build": "tsc -p tsconfig.json",
    "watch": "tsc -p tsconfig.json --watch"
  }
}

核心 API

显示 UI 弹窗

figma.showUI(__html__, {
  width: 360,       // 宽度,默认 300,最小 70
  height: 200,      // 高度,默认 200,最小 0
  title: '标题',    // 窗口标题
  visible: true,    // 是否显示,默认 true
  themeColors: false // 是否启用明暗主题 CSS 变量
});
  • __html__ 是全局变量,指向 manifest.json 中 ui 字段指定的 HTML 文件内容
  • figma.ui.hide() / figma.ui.show() 控制显示隐藏
  • figma.ui.resize(w, h) 动态调整大小
  • figma.ui.close() 销毁 UI

主线程与 UI 通信

主线程接收消息:

figma.ui.onmessage = (msg: { type: string }) => {
  if (msg.type === 'some-action') {
    // 处理消息
  }
};

UI 发送消息给主线程:

parent.postMessage({ pluginMessage: { type: 'some-action' } }, '*');

创建文字节点

// 1. 必须先加载字体(修改 textNode 的任何渲染属性前必须加载)
await figma.loadFontAsync({ family: 'Inter', style: 'Regular' });

// 2. 创建文字节点
const textNode = figma.createText();

// 3. 设置属性(字体已加载后才能设置)
textNode.characters = 'Hello';
textNode.fontSize = 50;
textNode.fontName = { family: 'Inter', style: 'Regular' };

// 4. 添加到页面
figma.currentPage.appendChild(textNode);

// 5. 定位
textNode.x = 100;
textNode.y = 200;

// 6. 选中
figma.currentPage.selection = [textNode];

关键约束: 在修改 charactersfontSizefontName 等会触发文字重新渲染的属性之前,必须先调用 figma.loadFontAsync() 加载对应字体。

获取可用字体

// 列出所有可用字体
const fonts = await figma.listAvailableFontsAsync();

// 使用第一个可用字体
if (fonts.length > 0) {
  await figma.loadFontAsync({
    family: fonts[0].fontName.family,
    style: fonts[0].fontName.style,
  });
}

TextNode 常用属性

属性 类型 说明
characters string 文字内容
fontSize number 字体大小,最小 1
fontName { family: string, style: string } 字体名称和样式
textAlignHorizontal 'LEFT' \| 'CENTER' \| 'RIGHT' \| 'JUSTIFIED' 水平对齐
textAlignVertical 'TOP' \| 'CENTER' \| 'BOTTOM' 垂直对齐
fills ReadonlyArray<Paint> 填充(颜色等)
letterSpacing LetterSpacing 字符间距
lineHeight LineHeight 行高
x, y number 位置坐标
width, height number (只读) 尺寸

文字范围操作

TextNode 支持按字符范围设置不同样式:

textNode.setRangeFontSize(0, 5, 24);   // 前5个字符字体大小24
textNode.setRangeFontName(0, 5, { family: 'Inter', style: 'Bold' });
textNode.setRangeFills(0, 5, [{ type: 'SOLID', color: { r: 1, g: 0, b: 0 } }]);

其他常用 API

// 通知
figma.notify('操作成功');
figma.notify('操作失败', { error: true });

// 关闭插件
figma.closePlugin();

// 视口
figma.viewport.center;  // { x: number, y: number }

// 当前页面
figma.currentPage;  // PageNode

// 选区
figma.currentPage.selection;  // readonly SceneNode[]

在 Figma 中加载插件

  1. 打开 Figma Desktop
  2. Plugins → Development → Import plugin from manifest...
  3. 选择 manifest.json 文件
  4. 插件出现在 Plugins 菜单中,点击即可运行

常见问题

TypeScript 找不到 figma 全局变量

原因:@figma/plugin-typingspackage.json"main": "",TypeScript 无法自动解析。

解决:在 code.ts 顶部添加:

/// <reference path="./node_modules/@figma/plugin-typings/index.d.ts" />

修改文字属性报错

修改 charactersfontSize 等属性前必须加载字体:

await figma.loadFontAsync({ family: 'Inter', style: 'Regular' });

插件 UI 不显示

检查 manifest.json 中 ui 字段是否正确指向 HTML 文件,以及 HTML 文件是否存在。