开发指南
在 简介 中,我们详细地介绍了插件的运行机制。在本节中,我们将带你从零开始构建一个可运行的插件。我们将要创建的插件能够接收用户输入的数字,并创建指定数量的椭圆图层。本节将涉及以下知识点:
- 什么是
manifest.json
文件,以及它的作用。 - 如何构建用户界面
- 如何调用插件 API
- 如何使用模板
- 如何使用 TypeScript 提升开发体验
- 如何在用户界面与主线程之间进行消息传递
manifest.json
manifest.json
文件非常重要,并且是每个插件必须包含的文件。它包含了插件的重要信息。下面是 manifest.json
文件的内容示例:
{
"name": "my-first-mastergo-plugin",
"id": 1234567890,
"api": "1.0.0",
"main": "./main.js",
"ui": "./ui.html",
"menu": [
{
"name": "打开主页面",
"command": "home"
},
{
"name": "执行B功能",
"command": "run"
},
],
"permissions": ["currentuser"]
}
name: string
用来指定插件的名称,该名称会出现在 “插件” 菜单栏。
id?: number
id
通常不需要手动指定,它用于插件的发布更新和通信隔离等,每个插件唯一。导入的manifest.json没有id,或者创建新插件时,系统会帮生成不重复的id。
api: string
用于指定插件所使用的 API 版本,我们推荐你总是使用最新的插件版本号,当前可使用 1.0.0
。
main: string
main
选项是一个相对路径,用来指定运行在沙箱中的 JavaScript 脚本。如:main: "./main.js"
。
ui: string
与 main
选项类似,ui
选项用来指定用户界面要加载的 HTML 文件路径,例如:ui: "./ui.html"
。
menu?: ManifestMenu[]
menu
选项是一个json数组,设置menu可以为插件添加子菜单入口,并调整菜单结构和分割线的位置。在运行时触发插件的 run 事件,其参数为选中的菜单中设置command
值,也可以通过 mg.command 获取。
若不设置menu,则为一级菜单入口,对应的command
值为空串
type ManifestMenuItem =
{ name: string; command: string; } // 设置可点击运行的子菜单结构
| { name: string; menu: ManifestMenuItem[] } // 设置子菜单结构
| { separator: true } // 设置分割线
permissions?: PluginPermissionType[]
permissions
属性设置后,该插件可使用该权限对应的接口。
type PluginPermissionType = "currentuser"
currentuser
: 设置后插件可使用mg.currentUser
接口。
创建一个插件
了解了 manifest.json
文件的作用之后,我们就可以着手创建插件了。
我们可以通过点击 “插件 -> 开发者模式 -> 创建/添加插件” ,输入插件名称来使用工程模板生成插件,这样的话,只需要跟随引导一步步来就可以了。
当然,我们也可以先在本地创建好插件,然后导入。这样的话,就需要我们先准备一下目录结构及文件:
my-plugin
├── manifest.json
├── main.js
├── ui.html
其中,manifest.json
的内容如下:
// manifest.json
{
"name": "my-plugin",
"id": "",
"api": "1.0.0",
"main": "./main.js",
"ui": "./ui.html"
}
没错,一个最小的插件已经创建完毕了,仅需要三个文件。接下来我们就开始构建用户界面。
构建用户界面
本质上,构建用户界面与开发传统 Web 应用没有任何区别。你甚至可以使用现代 Web 框架,如 Vue
、React
、Svelte
等等。不过,在本节的示例中,我们一切从简,即使用原生技术构建用户界面。
首先,在 ui.html
文件中编写如下 HTML 内容:
<!DOCTYPE html>
<body>
<div class="content">
<div style="margin-bottom: 20px; color: #fff;">
输入椭圆的数量:<input type="text" />
</div>
<button id="btn">创建</button>
</div>
</body>
然后在 main.js
中编写如下 JavaScript 代码:
// main.js
mg.showUI(__html__) // 用于展示插件用户界面
调试插件
下一步我们要做的,就是运行插件代码,看它是否按预期的那样来展示用户界面。为了调试插件,我们需要下载 MasterGo
客户端:点击下载
开发客户端下载完毕后,运行客户端。点击顶部 “插件” 菜单按钮,或在文件页画布内点击鼠标右键,调出 “插件” 菜单,点击 “开发者模式 -> 创建/添加插件”。如下图所示:
或在画布中右键菜单:“插件 -> 开发者模式 -> 创建/添加插件”:
此时,会弹出插件创建面板,如下图所示:
如上图所示,你既可以选择通过模板生成一个全新的插件;也可以选择已有的插件。由于我们已经创建了自己的插件,因此点击 "点击或拖动上传 manifest.json 文件" 按钮,并选择插件的 manifest.json
文件。如下图所示:
选择 manifest.json
文件后,不出意外的话会跳转到如下界面。
创建成功后的插件会出现在 顶栏菜单栏
和 具有编辑权限的 画布右键菜单
中 “插件 -> 开发者模式” 菜单下,点击插件名称运行此插件。
或在画布中右键菜单 “插件 -> 开发者模式”:
不出意外的话,我们将看到如下用户界面:
向主线程代码传递消息
现在,我们已经有了用户界面,并且可以通过 input
输入框接收用户输入。接下来我们要做的是,将用户输入的数量数据传递给主线程的 JavaScript 代码。
为了完成消息传递的任务,我们需要在 iframe
中调用 parent.postMessage
函数。如下面的代码所示:
<!DOCTYPE html>
<body>
<div class="content">
<div style="margin-bottom: 20px; color: #fff;">
输入椭圆的数量:<input type="text" />
</div>
<button id="btn">创建</button>
</div>
<script>
// 获取 input 表单
const input = document.querySelector('input')
// 为按钮绑定 click 事件
document.getElementById('btn').addEventListener('click', (ev) => {
// 当点击按钮时,将表单的值转为数字类型,并发送给主线程
parent.postMessage({ count: Number(input.value) }, '*')
})
</script>
</body>
主线程的代码需要监听 onmessage
事件,从而有能力接收由 iframe
发送过来的数据。这需要我们修改 main.js
代码,如下代码所示:
mg.showUI(__html__)
mg.ui.onmessage = (msg) => {
console.log(msg) // { count: 3 },假设用户在 input 框中输入数字 3
}
最后,重新运行插件并打开的开发者工具,如下图所示:
打开控制台后效果如下:
此时,如果你在输入框中输入数字 3
,并点击“创建”按钮,将会在控制台中看到主线程接收并打印出来的数据:{ count: 3 }
。
调用插件 API 创建椭圆图层
现在,主线程已经能够接收来自用户界面的数据了。接下来,只需要在主线程的代码中调用 MasterGo 插件 API 来创建椭圆图层即可。具体实现如下:
// main.js
mg.showUI(__html__)
mg.ui.onmessage = (msg) => {
const count = msg.count
for (let i = 0; i < count; i++) {
// mg 是全局变量,用来访问 MasterGo 提供的 API 接口
// mg.createEllipse() 可以创建椭圆图层
mg.createEllipse()
}
}
在调试过程中,我们可以使用快捷键来运行最近一次运行过的插件:
Windows 快捷键: Ctrl + Alt + P
Mac 快捷键: Command + Option + P
插件管理与插件发布
插件开发完成后就可以将插件发布到应用市场,让所有的 MasterGo 用户了解并安装你的插件。下面将介绍如何管理和发布插件。
插件发布
首先,打开 MasterGo 客户端,点击插件菜单,选择管理插件,如下图所示。
或在画布中通过右键菜单打开:
插件开发完成后就可以将插件发布到应用市场,让所有的 MasterGo 用户了解并安装你的插件。下面将介绍如何发布你的插件。
我们需要在 开发中
面板中找到我们要发布的插件,点击右侧按钮,点击发布。
选择发布到团队或是发布到社区,然后填写对应的发布信息,完成后点击发布按钮。
发布到社区的插件,会被所有用户看到,但需要先经过审核,审核通过后,方可在插件社区搜索到。
发布到团队的插件无需审核,发布成功后即可出现在团队成员的已安装列表中。
如果需要发布到社区,我们需要填写插件的详细信息,如插件 LOGO、插件名称、插件封面、插件介绍等:
如果需要发布到团队,则需要先选择目标团队:
然后填写插件的基本信息:
插件管理
我们安装的所有插件,均可在 已安装
列表中找到,包括团队插件和社区插件。
但是我们仅可以卸载社区插件,团队插件在 已安装
列表中是无法卸载的。
开发中
列表展示了所有我们正在开发的插件,开发中的插件我们可以选择发布或是移除,注意:移除不会删掉本地的代码,移除后的插件如果后续还想发布,只需要再导入即可。
在 审核中
列表中,我们可以选择取消发布插件。
在 未通过
列表中,我们可以查看插件被拒绝的原因。
已通过
的社区插件,将会出现在插件社区,并且不可下架或移除。当然,团队插件是可以从相关团队下架的。
模板的使用
在上面的教程中,我们已经详细了解了html模板的使用,接下来,我们来了解一下vue模板和react模板的创建和使用:
首先,我们在菜单中选择 “插件 -> 开发者模式 -> 创建/添加插件”,输入要创建的插件名字后点击下一步,进入到模板选择界面:
vue模板
选中 vue
模板并保存到本地之后,在 开发中
面板中,找到我们刚刚创建的模板:
可以看到,此时的插件是不可以直接运行的,提示 无法读取main文件
,不要慌张,出现这个提示是正常的,这是因为创建的模板需要先 build 一下,才能正常运行。
此时,我们需要在编辑器中打开刚刚创建好的模板项目,开始编写插件~
首先我们需要安装一下依赖,我们推荐使用 yarn
来进行安装:
yarn install
我们还是以上面的创建圆形代码为例
首先,我们在 ui/App.vue
中编写代码
<template>
<div style="margin-bottom: 20px; color: #fff;">
输入椭圆的数量:<input type="number" v-model="count" />
</div>
<button @click="create">创建</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'App',
setup() {
return {
count: 0,
}
},
methods: {
create() {
parent.postMessage({ count: this.count }, '*')
}
}
})
</script>
然后,在 lib/main.ts
中编写代码
mg.showUI(__html__)
mg.ui.onmessage = (msg) => {
const count = msg.count
for (let i = 0; i < count; i++) {
// mg 是全局变量,用来访问 MasterGo 提供的 API 接口
// mg.createEllipse() 可以创建椭圆图层
mg.createEllipse()
}
}
编写完成~
现在让我们来 build 一下~
yarn build
build完成后,可以看到,出现了一个新的文件夹: dist
文件夹,文件夹下面有两个文件:main.js
和 index.html
,就是我们刚刚新鲜出炉的插件代码~
此时,我们再打开 MasterGo
客户端,打开插件管理面板,可以看到,刚刚的红色提示 请配置main文件
已经消失不见啦,这就意味着,现在我们的代码可以正常运行了~
我们可以选择顶部插件菜单,或是画布右键 “插件 -> 开发者模式” ,点击我们刚刚编写完的插件 vue-plugin
, 运行插件:
当当当当!大功告成~
react模板
选中 react
模板并保存到本地之后,在 开发中
面板中,找到我们刚刚创建的模板:
可以看到,此时的插件是不可以直接运行的,提示 无法读取main文件
,不要慌张,出现这个提示是正常的,这是因为创建的模板需要先 build 一下,才能正常运行。
此时,我们需要在编辑器中打开刚刚创建好的模板项目,开始编写插件~
首先我们需要安装一下依赖,我们推荐使用 yarn
来进行安装:
yarn install
我们还是以上面的创建圆形代码为例
首先,我们在 ui/App.tsx
中编写代码
import { useState, useCallback } from 'react'
function App(){
const [value, setValue] = useState<number>(0);
const handleChange = useCallback((event) => {
setValue(parseInt(event.target.value));
}, []);
const create = () => {
parent.postMessage({ count: value }, '*');
}
return (
<div>
<div className="hello">
输入椭圆的数量:
<input type="number" value={value} onChange={handleChange} />
</div>
<button onClick={create}>创建</button>
</div>
);
}
export default App
然后,在 lib/main.ts
中编写代码
mg.showUI(__html__)
mg.ui.onmessage = (msg) => {
const count = msg.count
for (let i = 0; i < count; i++) {
// mg 是全局变量,用来访问 MasterGo 提供的 API 接口
// mg.createEllipse() 可以创建椭圆图层
mg.createEllipse()
}
}
编写完成~
现在让我们来 build 一下~
yarn build
build完成后,可以看到,出现了一个新的文件夹: dist
文件夹,文件夹下面有两个文件:main.js
和 index.html
,就是我们刚刚新鲜出炉的插件代码~
此时,我们再打开 MasterGo
客户端,打开插件管理面板,可以看到,刚刚的红色提示 请配置main文件
已经消失不见啦,这就意味着,现在我们的代码可以正常运行了~
我们可以选择顶部插件菜单,或是画布右键 “插件 -> 开发者模式” ,点击我们刚刚编写完的插件 react-plugin
, 运行插件:
当当当当!大功告成~
@mastergo/plugin-typings
TypeScript 类型支持
TypeScript 是一种可以编译到 JavaScript 的编程语言,它是 JavaScript 的超集,为 JavaScript 提供了类型支持。使用 TypeScript 的好处之一是它带来的类型提示和自动补全功能。MasterGo
的插件 API 提供了良好的 TypeScript 类型支持,因此配合 TypeScript 和 VSCode,你能得到极佳的开发体验:
为了获取到插件的类型文件,你需要安装 @mastergo/plugin-typings
:
yarn add @mastergo/plugin-typings
接着配置 tsconfig.json
文件:
{
"compilerOptions": {
// ...
"types": ["@mastergo/plugin-typings"]
}
// ...
}
便于开发插件的辅助函数
@mastergo/plugin-typings
除了为插件开发提供类型支持外,还提供了很多工具函数,这些工具函数可以提升你的开发效率。请查阅 Plugin Typings 文档