最近工作主要和 Figma 插件打交道,梳理一些踩坑的经验~

开始

官方的起始例子:www.figma.com/plugin-docs…

按步骤将插件文件保存到本地即可,调试时可以右键唤起插件,可以关注下几个功能入口:

  • Import plugin from manifest 导入本地插件
  • Open console 控制台调试
  • Run last plugin 加载最新的插件

目前 figma 插件开发流程没有有效的 hot reload 机制,【加载最新插件】在开发时比较常用,快捷键可以记一下。

插件架构

Figma 的插件架构比较简单,主要关注三部分:

  • manifest.json 插件清单
  • ui.html 入口
  • core.js 入口

manifest.json

{"name": "test","id": "1095700741264679376","api": "1.0.0","main": "code.js","editorType": ["figma"],"ui": "ui.html"
}

ui.html

<h2>Rectangle Creator</h2>
<p>Count: <input id="count" value="5" /></p>
<button id="create">Create</button>
<button id="cancel">Cancel</button>
<script> document.getElementById('create').onclick = () => {const textbox = document.getElementById('count');const count = parseInt(textbox.value, 10);parent.postMessage({ pluginMessage: { type: 'create-rectangles', count } }, '*');};document.getElementById('cancel').onclick = () => {parent.postMessage({ pluginMessage: { type: 'cancel' } }, '*');}; </script>

core.js

figma.showUI(__html__);
figma.ui.onmessage = msg => {if (msg.type === 'create-rectangles') {const nodes: SceneNode[] = [];for (let i = 0; i < msg.count; i++) {const rect = figma.createRectangle();rect.x = i * 150;rect.fills = [{type: 'SOLID', color: {r: 1, g: 0.5, b: 0}}];figma.currentPage.appendChild(rect);nodes.push(rect);}figma.currentPage.selection = nodes;figma.viewport.scrollAndZoomIntoView(nodes);}figma.closePlugin();
};

manifest

清单描述文件主要描述应用入口、支持编辑器类型还有一些权限相关的配置:

  • main 用于指定 figma 主应用进程的脚本文件,有点类似 chrome 插件中 background 进程
  • ui 用于直指定插件交互面板 html 入口,类似 chrome 插件的 popup 页面
  • editorType 用于指定插件支持的编辑器类型,编辑的类型有两种,具体的看区别这里

core

core.js 运行在 figma 应用所提供的沙箱环境,其只能使用 figma 所提供 API 与一些基本的 Javascript 特性包括标准类型、JSON 和 Promise API、与 Uint8Array 一类的二进制对象。,DOM 一类的接口是无法使用的,在 core 中尽量使用 figma 提供的 api 来实现目标操作,一些依赖 DOM API 的操作可以考虑交由 ui 页面来处理。

ui

UI 主要用于插件与用户的交互,本质是一个 figma 主页面中内嵌的 iframe 页面,其使用 postmessage 与 core 进行交互。

附:之前为了方便 core 与 ui 通信还写了个页面通讯工具库 rpc-shooter 有兴趣的同学可以瞧瞧。

想具体了解插件的运行机制可以戳 How Plugins Run。

环境搭建

Vite 这段时间使用下来体验十分友好,下面以 Vite 为例搭建一个 Figma 插件开发环境。

示例的仓库地址:github.com/kinglisky/f…

yarn create vite

这里选用的 Vue 与 TS,框架随意,Figma 插件开发建议使用 TS,接入 figma plugin 的 d.ts 可以方便的当文档使用。

figma plugin 的类型支持需要配置下 tsconfig.json

yarn add @figma/plugin-typings -D
{"compilerOptions": {...other,"typeRoots": ["./node_modules/@types", "./node_modules/@figma"]}
}

多入口

Figma 插件中我们只关心两个入口文件:

  • ui.html
  • core.js

两个入口文件相互独立,需要将 ui 与 core 拆分成两个包来维护,整理下目录结构拆分出 ui 与 core 部分,示例中还拆分了一个 common 包用于提供公共配置:

.
├── lerna.json
├── manifest.json
├── package.json
├── packages
│   ├── common
│   │   ├── constants
│   │   │   └── ui.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── core
│   │   ├── favicon.svg
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   └── ui
│       ├── index.html
│       ├── package.json
│       ├── src
│       │   ├── App.vue
│       │   ├── env.d.ts
│       │   ├── main.ts
│       │   └── styles
│       │       └── index.css
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
├── scripts
│   └── build.js
├── tsconfig.json
└── yarn.lock

github.com/kinglisky/f…

workspaces

本地进行多包开发时,workspaces 是个很好用的功能,可以将本地包作为依赖来使用,有点类似 webpack 的中 alias 配置将依赖指向本地。

将 packages 目录下的所有包做作为本地依赖:

{"private": true,"workspaces": ["packages/*"],...
}

插件中实际 core 与 ui 都会从 common 中读配置,common 包的 package.json 配置下 name 与 module 即可提供给 core 与 ui 使用:

{"name": "figma-vite-common","private": false,"version": "0.0.0","module": "./","types": "./"
}

core 与 ui 使用时:

import { VIEW_WIDTH, VIEW_HEIGHT } from 'figma-vite-common/constants/ui';

构建配置

有一点需要注意一下,core.js 与 ui.html 作为插件的入口文件只能是个单文件,简单来说就是不能拆分文件,不能使用异步模块导出多个文件。

  • core 中所有依赖的资源都打包到 core.js
  • ui.html 中所有的资源都会以内联形式存在

core 配置

core 的配置比较简单:

import { resolve } from 'path';
import { defineConfig } from 'vite';export default defineConfig({build: {lib: {entry: resolve(__dirname, 'src/index.ts'),formats: ['iife'],name: 'core',fileName: 'core',},outDir: resolve(__dirname, '../../dist'),},
});

由于不需要发包使用,将最终打包的 core 入口格式配置为 iife (立即执行的函数表达式模块),简单的包一层立即调用函数即可:

// 构建结果
(function () {'use strict';figma.showUI(__html__, { width: 400, height: 490 }),(figma.ui.onmessage = (o) => {if (o.type === 'create-rectangles') {const t = [];for (let i = 0; i < o.count; i++) {const e = figma.createRectangle();(e.x = i * 150),(e.fills = [{ type: 'SOLID', color: { r: 1, g: 0.5, b: 0 } }]),figma.currentPage.appendChild(e),t.push(e);}(figma.currentPage.selection = t),figma.viewport.scrollAndZoomIntoView(t);}figma.closePlugin();});
})();

对应的配置下 package scripts:

{"name": "figma-vite-core","private": false,"version": "0.0.0","scripts": {"start": "tsc && vite build -w","build": "tsc && vite build"},"dependencies": {"figma-vite-common": "*"},"devDependencies": {"@figma/plugin-typings": "^1.42.1","typescript": "^4.5.4","vite": "^2.8.0"}
}

开发时会以 yarn start 启动, -w 监听文件变动触发构建。

ui 配置

ui 由于最终的构建产物是一个 html 文件,其他的构建的资源需要内联,这里需要将各种代码拆分的配置关闭,内联资源的阈值调大:

import { resolve } from 'path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { viteSingleFile } from 'vite-plugin-singlefile';export default defineConfig({plugins: [vue(), viteSingleFile()],build: {target: ['es6'],assetsInlineLimit: 100000000,chunkSizeWarningLimit: 100000000,cssCodeSplit: false,brotliSize: false,outDir: resolve(__dirname, '../../dist'),rollupOptions: {inlineDynamicImports: true,output: {format: 'iife',manualChunks: () => 'everything.js',},},},
});

vite-plugin-singlefile 插件用于将构建出的 js 资源内联到 html 中,构建的包格式还是 iife

package scripts 配置:

{"name": "figma-vite-ui","private": false,"version": "0.0.0","scripts": {"start": "vue-tsc --noEmit && vite build -w","build": "vue-tsc --noEmit && vite build"},"dependencies": {"figma-vite-common": "*","vue": "^3.2.25"},"devDependencies": {"@figma/plugin-typings": "^1.42.1","@vitejs/plugin-vue": "^2.2.0","sass": "^1.49.7","typescript": "^4.5.4","vite": "^2.8.0","vite-plugin-singlefile": "^0.6.3","vue-tsc": "^0.29.8"}
}

同样使用 yarn start 启动,-w 监听变动构建。

启动入口

实际在插件开发时需要同时启动 core 与 ui,所以可以在根目录下配置个启动命令,可以直接使用 lerna 进行启动。

配置 lerna.json

{"packages": ["packages/*"],"version": "0.0.0","npmClient": "yarn","useWorkspaces": true
}

配置 package.json

{"private": true,"workspaces": ["packages/*"],"scripts": {"start": "lerna run --stream --scope figma-vite-ui --scope figma-vite-core start"},"publishConfig": {"access": "public"},"devDependencies": {"lerna": "^4.0.0"},"name": "fgima-vite"
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1gEnVZq-1653620813636)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4767aab3122348879f3945c74209cb85~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

最后改一下插件manifest.json 中入口文件的路径:

{"name": "figma-vite-demo","id": "","api": "1.0.0","main": "dist/core.iife.js","ui": "dist/index.html","editorType": ["figma"]
}

自此一个简单 Figma 插件开发环境完成,仓库在这 github.com/kinglisky/f…

其他

有空会梳理下 Figma 文档数据结构与一些解析技巧,先这样~

Figma 插件开发 - Vite 环境搭建相关推荐

  1. vue3+vite环境搭建 vue3+vite实战

    目录 1.安装 vue-cli 3 2.安装vite 3.安装成功后**package.json**中会添加 4.通过@vitejs/plugin-vue插件来支持Vue 5.安装路由 6.在入口文件 ...

  2. 3dsmax2014插件开发之环境搭建

    做一个记录.防止做到一半以后忘了.网上CSDN等也各有操作流程,参考他们的操作帮忙加了一些速度,但是毕竟每个人遇到的坑点是不一样的,(而且网上好像都是3dmax2022插件制作,我做2014的话可能会 ...

  3. iphone cydia插件开发_环境搭建

    以前从没弄过IOS相关的开发,突然想知道iphone越狱后的插件是怎么开发,刚刚又有相关的设备,于是从零做起. 第一步,安装MacPorts 这个东西类似于linux下面的 apt-get和yum,是 ...

  4. Atlassian JIRA 插件开发之一 环境搭建

    参考 https://developer.atlassian.com/server/framework/atlassian-sdk/  download the SDK 说明 Download the ...

  5. Vue 3 组件开发:搭建基于SpreadJS的表格编辑系统(环境搭建)

    Vue是一套用于构建用户界面的渐进式框架,与其它大型 JS 框架不同,Vue 被设计为可以自底向上逐层应用,更易上手,还便于与第三方库或既有项目整合,因此,Vue完全能够为复杂的单页应用提供驱动. 2 ...

  6. Flutter环境搭建、运行gallary项目

    Flutter环境搭建.运行gallary项目 主体步骤 1.从github clone flutter的sdk, git clone -b beta https://github.com/flutt ...

  7. 初识 ThreeJS (ThreeJS 相关环境搭建)

    初识 ThreeJS (初识 ThreeJS (ThreeJS 相关环境搭建) 参考 描述 ThreeJS 在本地搭建 NodeJS 的官方网站 获取 使用 安装依赖项 运行 官方文档 案例 场景编辑 ...

  8. tinymce系列(一) tinymce 环境搭建

    文章目录 tinymce 环境搭建 初始化目录结构 使用 Rollup 运行,打包 Rollup 打包效果 新建 2 个插件,编写 rollup.config.js rollup 配置 ES6 转 E ...

  9. Ionic+Cordova开发环境搭建

    Ionic+Cordova的组合是一个跨平台的移动开发框架,属于HybirdApp开发模式.其中Ionic是一个前端框架,集成了AngularJs在里面,有很好很漂亮的UI控件.Cordova本身就是 ...

最新文章

  1. python为什么运行慢_为什么你写的Python运行的那么慢呢?
  2. CSS题目系列(1) - 可滚动的Table
  3. 静态html使用js发送邮件,html实现邮箱发送邮件_js发送邮件至指定邮箱功能
  4. AutoMapper入门使用
  5. ITK:删除一个未连接到其边界的二进制图像中的孔
  6. source insight3.5显示中文_Doxygen 中文文档
  7. java删除通用方法_一个比较通用的java删除文件和文件夹的方法
  8. Ajax Control Toolkit--Slider:有朝一日倒过来
  9. golang延时_Golang 定时器底层实现深度剖析
  10. 分析LOIC流,判断DDoS攻击源
  11. 计算机操作系统——进程调度算法
  12. MATLAB牛拉法计算潮流,Matlab牛拉法潮流计算程序
  13. Adobe Premiere(Pr视频剪辑)下载安装
  14. Python - 安装sentencepiece异常
  15. PG-Strom学习总结
  16. 2014Gartner技术成熟度曲线
  17. 解决Destroying ProtocolHandler [“ajp-apr-8009“]
  18. 康宇的OJ愚人手账1
  19. 快速实现Thread Mesh组网详解
  20. Ubuntu清理系统垃圾 命令

热门文章

  1. QT:QSS字体设置
  2. utf-8等编码方式汉字和英文各占据的字节数
  3. ie兼容性问题:页面内容显示不全,但不会出现滚动条
  4. 魅族手机计算机视频教程,魅族手机屏幕电脑录制教程
  5. 腾讯出品:6.4亿短视频用户的狂欢洞察报告
  6. 新闻!牛磨王爸爸谈牛磨王抗磨网 | “绿多多”绿色资产
  7. PacketiX ××× 3.0在Windows Server服务器NT配置步骤
  8. js设置注册表中ActiveX,并添加信任站点解决IE弹出安全警告
  9. 用google去旅游!
  10. 【优化布局】基本蚁狮算法在WSN节点部署中的应用matlab源码