今天 utools 更新了第三方插件, 并且提供了初步的开发文档
我花了一点时间尝试了一下, 鉴于官网上也没有给出demo, 那我就简单地用代码展示一下插件的开发.
我实现了一个简单的命令行调用插件, 作为这次尝试的demo




总的来说, 插件开发还是非常简单的, 插件工程目录里最少只需要2个文件即可构成一个插件, 分别是index.html和plugin.json, 其中plugin.json是插件的说明信息, index.html是插件的本体.

刨去plugin.json和preload.js这两个 utools 插件特有的文件, 剩下的文件放在一起很显然就是一个传统的 web 工程, 也就是说插件就是一个 web 页面.
在plugin.json定义的是一些插件的信息, 就像身份证一样, 作者, 描述, 版本, 插件的入口等等, 文档里描述得比较清楚, 就不赘述了.
{
"pluginName": "命令行调用",
"version": "0.0.1",
"description": "调用命令行执行命令",
"author": "lanyuanxiaoyao",
"homepage": "http://lanyuanxiaoyao.com",
"main": "index.html",
"preload": "preload.js",
"logo": "logo.png",
"pluginSetting": {
"single": true
},
"features": [
{
"code": "命令行",
"explain": "命令行",
"cmds": [
">", "cmd", "command"
]
}
]
}
接下来是插件的本体, 在这里我习惯性地用了 vue 来写, 但是也不影响主要逻辑, 因为比较简单, 大意就是获取输入框输入的命令, 然后调用相关的函数在 shell 里执行一下, 如果有返回值的话, 就展示在插件页面上, 如果没有的话, 就什么也不发生. (除了 vue 之外, 还顺便引入了 element-ui, 但是这不影响主要逻辑, 忽略即可.)
<!DOCTYPE html>
<html lang="zh">
<head>
<link rel="stylesheet" href="./element.css" />
</head>
<body>
<div id="app">
<el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="content" autosize resize="none" readonly />
</div>
</body>
</html>
<script src="./extra.js"></script>
<script src="./vue.js"></script>
<script src="./element.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
content: '',
command: ''
},
mounted: function () {
var self = this
// 进入插件执行的事件
utools.onPluginEnter(({ code, type, payload }) => {
// 将插件主界面的高度设为0, 即隐藏插件界面, 因为这个时候我们的这个插件只需要一个输入框而已
utools.setExpendHeight(0)
// 等待二次输入的回调方法
// 将输入的内容更新到 command 变量里, 交给其他函数使用
utools.setSubInput(({ text }) => {
self.command = text
}, '输入要执行的命令')
})
// API 里并没有回车键按下的事件, 所以监听事件要自己写
// 监控回车键按下的事件
document.onkeydown = function (e) {
var keyCode = window.event ? e.keyCode : e.which
if (keyCode == 13) {
if (self.command === '') {
return
}
window.exec(self.command, (content) => {
self.content = content
// 如果命令行调用有返回结果的话, 就把插件页面展示出来
if (content !== '') {
utools.setExpendHeight(500)
}
})
}
}
}
})
</script>
除了基础的两个文件外, 如果需要用到node.js或者electron提供的一些功能, 就要再加入一个preload.js的文件, 这个文件可以理解为一个中间层, 用来把插件的页面和底层的框架连接起来, 在连接的同时也做了隔离, 方式底层 API 被滥用.
在这个文件里的事情也比较简单了, 就是做了一个名为exec的扩展函数, 让页面上的代码可以调用child_process模块.
console.log('preLoad')
const { exec } = require('child_process')
window.exec = function (command, callback) {
exec(command, (err, stdout, stderr) => {
if (err) {
callback(stderr);
return;
}
callback(stdout)
})
}
到这里, 一个插件的开发就已经完成了, 只要复制一下plugin.json文件, 然后眼疾手快地打开 utools, 就可以导入模块到 utools 里了, 当然, 对于以上展示的这个模块来说, 可以完善的东西还有很多, 这里仅仅是做一个示范.
希望大家能玩得愉快.
当然, 在开发的过程中还是遇到了一些不愉快的事情
1. 插件如果没有退出的情况下重新加载 plugin.json, utools 会卡死, 只能选择重启.
2. utools.setSubInput的用法感觉有点古怪, 我一开始以为只要在最外层写了就会开启二级输入, 但是并没有, 只有写在utools.onPluginEnter里才起作用, 希望在文档里能说明这一点.