Penpot 插件开发实战指南:运行官方示例插件与从零构建自定义插件

发布时间:2026/9/8 18:11:55
Penpot 插件开发实战指南:运行官方示例插件与从零构建自定义插件 Penpot 插件开发实战指南运行官方示例插件与从零构建自定义插件【免费下载链接】penpotPenpot: The open-source design platform for Product teams that need scalable collaboration.项目地址: https://gitcode.com/GitHub_Trending/pe/penpotPenpot 的插件体系Penpot Plugins为开源设计平台提供了一个可扩展的运行时与一整套官方示例。本指南以仓库中 plugins/README.md 为核心讲解如何定位plugins/插件工作区中的libs运行库与apps示例应用两大目录、如何在本机启动示例插件并在 Penpot 中通过 manifest 清单加载以及从零创建自定义插件的完整路径。读完本文你将能够独立完成 Penpot 插件开发环境的搭建、示例插件的运行验证并为编写自己的第一个插件做好准备。一、先认识plugins/仓库中独立的插件子工程在当前 Penpot 仓库根目录下的 plugins/ 中维护着一套以插件为中心的独立 pnpm 工作区它拥有自己的 package.json、angular.json与pnpm-workspace.yaml内部按用途划分为apps、libs、docs、tools等子目录。这一阶段的产品形态是官方文档中所述的一个MVP最小可行产品一方面允许用户使用官方提供的既有插件另一方面支持开发者编写自己的插件。按照plugins/README.md的说明有两个最重要的目录apps与libs。plugins/ ├── apps/ # 可直接运行的示例插件、插件测试套件与样式 showcase ├── libs/ # 插件运行时的公共库runtime、styles、plugin-types ├── docs/ # 从零创建插件、创建 Angular 插件、发布、e2e 等文档 ├── tools/ # 构建脚本build-plugin.mjs与发布脚本 ├── angular.json # 所有示例插件的 Angular 构建/开发服务器配置 └── package.json # 工作区级脚本入口libs/插件开发的三件套基座libs/目录集中存放插件体系的公共代码是理解插件如何运转的钥匙plugins-runtime插件运行时的核心库。官方描述它是“负责生成 API 并加载 Penpot 插件”的代码具体职责包括初始化插件运行环境、建立沙箱sandbox、解析 manifest 清单以及设置若干监听器以便获知 Penpot 的页面page、文件file、选区selection何时发生变化。它的入口在 src/index.ts。plugins-styles一份可独立发布的 Penpot 风格 CSS 基础库npm 包penpot/plugin-styles。当你需要让自己的插件 UI 与 Penpot 主界面视觉一致时可直接引入其样式。包内含按钮、复选框、图标、输入框、单选、下拉选择、开关等组件样式以及字体、间距、色板等基础 token。plugin-typespenpot/plugin-types提供 Penpot 插件 API 的 TypeScript 类型定义配合typeRoots/types配置即可获得类型提示与 IDE 支持是插件开发中最常用的一层。其类型声明见 plugins/libs/plugin-types/index.d.ts。注意虽然plugins/README.md只重点列举了 runtime 与 styles 两个库但libs/plugin-types同样是该工作区的正式成员且被 runtime 直接依赖见 plugins-runtime/package.json 中的penpot/plugin-types: workspace:^。apps/示例插件与测试套件apps/目录下是使用上述libs编写的具体示例既可用于演示也可作为新插件开发的起点。从仓库结构看当前包含 9 个示例插件如 contrast-plugin、icons-plugin、lorem-ipsum-plugin、create-palette-plugin、table-plugin、rename-layers-plugin、colors-to-tokens-plugin、poc-state-plugin、poc-tokens-plugin、2 个插件测试套件plugin-api-test-suite、composable-test-suite、1 个样式 showcaseexample-styles以及端到端测试目录e2e。每个插件大致由 Angular 工程骨架、src/plugin.ts主逻辑与src/manifest.json清单三部分组成。二、运行示例插件从安装依赖到在 Penpot 中加载前置条件本机先有可用的 Penpot启动任何 Penpot 插件前都需要一个正在运行的 Penpot 实例插件要挂在 Penpot 的页面/文件上下文上执行。本机开发环境的搭建不在本仓库插件子工程范围内可参照仓库根目录下的开发环境devenv指南 以及 docker/devenv 目录下的编排配置完成。第一步安装工作区依赖在终端进入plugins/工作区目录使用 pnpm 递归安装全部子包依赖pnpm -r install该命令会同时解析apps/*、libs/*等所有 filter 子包的依赖。从根级 package.json 可看到本工作区固定使用pnpm11.20.0packageManager字段建议使用与之匹配的 pnpm 版本。第二步启动插件运行时Runtime继续执行pnpm run startstart实际指向start:app:runtime其实现为一条concurrently命令同时执行两部分工作见 plugins/package.jsonpnpm --filter penpot/plugins-runtime run build:watch以 watch 模式持续构建 runtime 库pnpm --filter penpot/plugins-runtime run preview预览构建产物开发服务器固定监听4200端口见 vite.config.ts 中的preview.port: 4200。启动后运行时子包会处于“随时可被 Penpot 前端调用”的构建/预览状态。第三步启动所选示例插件保持上一步的进程运行另开一个新的终端标签页执行该插件的启动脚本。以 README 中的 Contrast对比度检测插件为例pnpm run start:plugin:contrast该脚本指向pnpm --filter contrast-plugin run init实际由concurrently同时拉起“watch 构建插件产物”与ng serve contrast-plugin两个进程见 apps/contrast-plugin/package.json。由于 Angular 在 watch 模式下会把src/manifest.json等静态资源同步到构建产物中因此插件本体与清单会同时可用。第四步在浏览器/Penpot 中加载插件示例插件自身的界面运行在 Angular 开发服务器上随后在 Penpot 界面中通过插件管理器输入该插件的Manifest URL完成安装与加载打开浏览器访问插件的开发服务器地址在 Penpot 内按快捷键Ctrl Alt P唤起插件管理器弹窗也可通过菜单进入粘贴该插件的 manifest 地址例如http://localhost:4202/assets/manifest.json完成安装安装成功后即可随时从插件入口打开它。端口说明README 正文示例中 Contrast 插件写的是http://localhost:4302但就当前仓库实际配置而言所有示例插件的 Angular 开发服务器端口在根级 angular.json 中均被设置为4202表格中的 Manifest URLhttp://localhost:4202/assets/manifest.json才是当前唯一准确的口径。由于全部插件共用 4202 端口同一时刻请只运行一个示例插件。各插件的具体启动方式见下节表格README 中给出了完整的“插件→启动命令→端口→Manifest URL”对照表下文将原样保留并补充注解。三、示例插件与 Web 应用清单示例插件Sample pluginsPlugin描述PORT启动命令Manifest URLpoc-state-plugin用于测试新插件 API 功能的沙箱插件4202pnpm run start:plugin:poc-statehttp://localhost:4202/assets/manifest.jsoncontrast-plugin提供颜色对比度信息的示例插件4202pnpm run start:plugin:contrasthttp://localhost:4202/assets/manifest.jsonicons-plugin从 Feather 图标库添加图标的工具4202pnpm run start:plugin:iconshttp://localhost:4202/assets/manifest.jsonlorem-ipsum-plugin生成 Lorem ipsum 占位文本4202pnpm run start:plugin:loremipsumhttp://localhost:4202/assets/manifest.jsoncreate-palette-plugin创建包含全部色板颜色的画板4202pnpm run start:plugin:palettehttp://localhost:4202/assets/manifest.jsontable-plugin创建或导入表格4202pnpm run start:table-pluginhttp://localhost:4202/assets/manifest.jsonrename-layers-plugin批量重命名图层4202pnpm run start:plugin:renamelayershttp://localhost:4202/assets/manifest.jsoncolors-to-tokens-plugin生成设计 Token 的 JSON 文件4202pnpm run start:plugin:colors-to-tokenshttp://localhost:4202/assets/manifest.jsonpoc-tokens-plugin用于测试 Token 相关功能的沙箱插件4202pnpm run start:plugin:poc-tokenshttp://localhost:4202/assets/manifest.json启动任意一行命令后插件界面都通过4202端口对外服务manifest 统一从/assets/manifest.json暴露——这是因为根级 angular.json 将各apps/*-plugin/src/manifest.json声明为静态资源构建后落入assets目录。Web 应用Web AppsApp描述启动命令plugins-runtime插件子系统运行时pnpm run start:app:runtime即pnpm run startexample-styles可应用于插件的 Penpot 样式 showcasepnpm run start:app:styles-example两点与 README 相关的口径勘误均以仓库代码为准example-styles 的启动脚本应使用pnpm run start:app:styles-example指向pnpm --filter example-styles dev。README 正文中出现的旧命令pnpm run start:styles-example在当前根级 package.json 中并不存在。其开发服务器实际监听端口是4202见 apps/example-styles/vite.config.ts 中server.port: 4202README 中“Web Apps 表”标注的 4201 与正文中的地址以源码配置为准即可。它展示的正是plugins-styles库中的各组件样式其页面入口见 apps/example-styles/src/main.ts。示例插件的代码长什么样以 Contrast 插件为例其主逻辑位于 apps/contrast-plugin/src/plugin.ts演示了 Penpot 插件 API 的几种典型用法penpot.ui.open(CONTRAST PLUGIN, ?theme${penpot.theme}, { width: 285, height: 525, }); penpot.on(selectionchange, () { /* 读取 penpot.selection 并通知 UI */ }); penpot.on(themechange, () { /* 主题切换同步 */ });而它的清单 apps/contrast-plugin/src/manifest.json 则声明了自己需要的最小权限{ name: Contrast, description: Measure contrast plugin, version: 2, code: assets/plugin.js, icon: assets/icon.png, permissions: [content:read] }四、库源码速览插件运行时的加载与沙箱机制如果你想知道“插件究竟如何被加载、如何拿到权限”答案都在libs/plugins-runtime的源码中。这一节以源码为据把 README 中“runtime 会初始化插件并注册若干监听器”这句描述展开讲清楚。Manifest 清单的强约束运行时使用 zod逐字段如下字段类型说明pluginIdstring插件的唯一标识namestring插件名称hoststring(url)插件宿主来源地址codestring插件入口脚本地址iconstring(可选)图标地址versionnumber(可选)清单版本descriptionstring(可选,≤200)插件描述最长 200 字符permissions枚举数组逐项授予的权限其中permissions是一组白名单枚举content:read、content:write、library:read、library:write、user:read、comment:read、comment:write、allow:downloads、allow:localstorage、clipboard:read、clipboard:write。插件申请的权限直接决定它能调用 API 的哪些能力——例如 plugin-types 的 index.d.ts 中多处标注“Requires thecontent:readpermission”监听事件同样要求先具备content:read。从 Manifest URL 到插件实例的调用链运行时对外暴露的核心入口见 src/index.tsinitPluginsRuntime(contextBuilder)会把构造插件上下文Context的回调、加载函数挂到全局随后由 Penpot 前端按需调用。加载过程的核心实现位于 lib/load-plugin.ts关键链路为ɵloadPluginByUrl(manifestUrl)先通过loadManifest拉取并解析 manifestloadPlugin(manifest)通过contextBuilder构造该插件专属的Context含当前文件、页面、库、字体、用户等信息并将其放入SESSecure ECMAScript沙箱中harden加固后再传给插件代码createPlugin真正实例化插件注册消息监听并在插件关闭时从已加载列表移除卸载ɵunloadPlugin(id)按pluginId查找并关闭对应插件。值得注意的一个设计是运行时在加载新插件时会先closeAllPlugins()关闭全部已加载插件见 load-plugin.ts 中closeAllPlugins实现即同一时刻只允许一个插件处于活动状态。页面/文件/选区变化的监听机制README 提到 runtime “sets a few listeners to know when the penpot page/file/selection changes”。这套能力最终以类型化事件的形式暴露给插件作者——即 plugin.model.ts 中定义的RegisterListenerpenpot.on(type, handler, props?)返回一个symbol句柄配合penpot.off(listener)取消订阅。可订阅的事件如selectionchange、shapechange、themechange由penpot/plugin-types的EventsMap统一定义示例插件已经展示了它们的实际用法。五、从零创建插件官方推荐的下一个学习路径运行完示例后README 明确指引开发者阅读 插件创建指南create-plugin.md。该指南描述了在penpot-plugins工作区内部新建插件的完整步骤初始化目录结构新建apps/name/src与apps/name/public编写最小package.json编写清单在 public 目录创建manifest.json声明name、host、code、icon与所需permissions完整示例见该文档配置构建在vite.config.ts中指定src/plugin.ts为入口产出plugin.js接入类型在tsconfig的 include 中加入../../libs/plugin-types/index.d.ts即仓库内实际的插件类型路径本地预览pnpm --filter plugin-name dev或build preview在 Penpot 中加载Ctrl Alt P打开插件管理器粘贴 manifest URL 完成安装。除上述“通用型”创建方式外仓库还提供Angular 技术栈的等价指南 create-angular-plugin.md以及围绕 API 的进阶资料插件 API 文档、API 文档生成说明、端到端测试指南test-e2e 与发布插件包说明publish-package。工作区还为测试套件提供了专门脚本例如根级package.json中的pnpm run test:e2e--filter e2e test用于运行插件端到端测试。六、常见问题与实用提示端口冲突runtime 预览固定占4200全部示例插件与 example-styles 共用4202。若浏览器访问不到先确认是否有其他进程占用且示例插件一次只启动一个。依赖缺失报错首次使用请务必先执行pnpm -r install并保证 pnpm 版本与仓库packageManager声明pnpm11.x兼容。修改插件后如何生效每个插件的init脚本都包含 watch 模式Angular serve 插件产物 watch 构建保存源码后浏览器刷新即可看到变化无需重启整个流程。权限申请原则manifest 中的permissions是插件 API 能力的“门禁”请只声明真正需要的权限——这与运行时在 manifest.schema.ts 中对权限做白名单校验的机制直接相关。manifest 位于assets下Angular 系插件的清单由构建过程从src/manifest.json拷贝为assets/manifest.json因此安装地址统一形如http://localhost:4202/assets/manifest.json。七、许可证plugins/子工程与 Penpot 主项目一致采用Mozilla Public License 2.0MPL-2.0版权归 KALEIDOS SUBSIDIARY SL 所有完整声明见 plugins/LICENSE。这意味着你可以自由使用、修改与再分发本工作区代码但需遵循 MPL-2.0 的源码公开义务并在分发时保留版权与许可声明。相关文档与源码索引工作区总览plugins/README.md运行时库说明与实现plugins-runtime README · 运行入口 src/index.ts · 加载器 load-plugin.ts样式库plugins-styles README · CSS 入口 styles.css类型定义plugin-types README · index.d.ts示例插件Contrast manifest · plugin.ts插件开发文档create-plugin.md · create-angular-plugin.md · api-docs.mdPenpot 本地开发环境devenv 指南【免费下载链接】penpotPenpot: The open-source design platform for Product teams that need scalable collaboration.项目地址: https://gitcode.com/GitHub_Trending/pe/penpot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询