直接开发扩展
不推荐此开发方式,除非你非常清楚自己在做什么,并且需要很高的自由度,否则请使用
extprg 工具链
扩展包格式
com.example.hello-world.prg/
├── metadata.msgpack (必须存在)
├── extension.js (必须存在)
├── README.md (插件说明文件)
├── icon.png (插件图标文件)
└── ...一个扩展就是一个文件夹或者 prg 文件(没错,就是工程文件的格式),里面必须包含 metadata.msgpack 和 extension.js 两个文件
插件的图标支持 png, jpg, svg, webp 等常见格式,建议使用正方形、同时避免文件体积过大。如果同时存在 icon.png 和 icon.svg,会优先使用 svg 格式的图标。
具体的优先级顺序:svg > webp > png > jpg
最简插件整体开发流程
- 创建一个插件项目文件夹
- 在项目中创建
metadata.json和extension.js文件、并按正确格式编写它们 - 将
metadata.json中的内容转换成metadata.msgpack二进制文件 - 将插件项目文件夹打包成一个 prg 文件
metadata文件
其中 metadata.msgpack 和工程文件有所不同,扩展包的元数据需要写在 extension 字段里
{
"version": "2.0.0",
"extension": {
"id": "com.example.hello-world",
"name": "示例扩展",
"description": "这是一个用于演示的示例扩展包",
"version": "1.0.0",
"author": "Author <[email protected]>"
}
}metadata字段解释
id: 扩展的唯一标识符,建议使用反向域名命名法,例如com.example.hello-world,将会与文件名保持一致name: 扩展的名称,仅作展示description: 扩展的描述,仅作展示version: 扩展最低支持的软件的prg文件版本,不是软件本身的版本号extension.version: 扩展本身的版本号,建议遵循语义化版本规范author: 扩展的作者信息,邮箱可选填
json文件 转 msgpack文件
如何生成或者编辑msgpack二进制文件?可以先写json文件,然后将json文件中的内容一次性转换成msgpack二进制文件,可以使用这个在线工具:
https://graphif.github.io/json2msgpack/
插件的metadata文件是否可以直接支持使用json文件,以便于编辑和维护,有待商榷。
extension.js 文件
extension.js 是扩展的入口文件
此示例展示了如何注册一个快捷键,当用户依次按下 q u e s 时,给当前选中的节点添加一个问号,并修改节点颜色
await prg.keybinds_register(
"ques",
{ $lucide: "User" },
"q u e s",
Comlink.proxy(async () => {
const project = await prg.tabs_getCurrentProject();
const stageManager = await project.stageManager;
const selectedEntities = await stageManager.getSelectedEntities();
const first = await selectedEntities[0];
const text = await first.text;
await first.rename(`❓ ${text}`);
first.color = { _: "Color", r: 255, g: 0, b: 0 };
await prg.toast_success("添加了问号并修改了节点颜色");
}),
);不需要 import prg,直接就可以使用API。
运行环境
- Web Worker: 扩展在一个独立的线程中运行,无法直接访问 DOM 和主线程的变量
- ES Module: 不能用
importScripts - Blob URL: 不能导入其他模块,但是可以用 CDN 的方式导入第三方库
- Async IIFE: 可以用顶层 await
自动注入的 API
扩展在启动时会自动且强制地注入一些 API
Comlink: 用于和主线程之间通信,建议使用prg来调用主线程的 API,Comlink用于调用Comlink.proxy等方法Comlink.transferHandlers: 详见 Transfer Handlersprg:Comlink.wrap(self)的结果,可以通过它调用主线程暴露的 API
打包prg文件
最终的插件产物是一个prg文件。如何将插件项目文件夹打包成一个 prg 文件?
- 进入插件项目文件夹
- 多选、选中所有文件
- 右键 -> 压缩(Compress) -> 会生成一个 zip 文件
- 将 zip 文件的后缀改成 prg 即可
为什么不能直接把整个文件右键压缩成一个 zip 文件?因为如果直接右键压缩整个文件夹,解压后会多一层文件夹,而插件需要的结构是所有文件直接放在根目录下。