实现工具自由,开源的桌面工具箱( 二 )


1.3 灵感
直到有一天 , 上看到这样一个沸点:
实现工具自由,开源的桌面工具箱
文章图片

文章图片
下面有个评论提到了 uTools 这是我第一次和 uTools 产生了交集 , 在体验了 uTools 功能后 , 我长吸一口气:这不就是我想要的嘛!然后就去 GitHub 上找 uTools 的源码 , 发现它并没有开源 。
所以就想把上面提到的那些工具 ,发布到 uTools 市场在 uTools 里通过插件的方式使用他们 。但我发现发布插件只能发布到公网 , 但这又涉及到数据安全的问题 。
无奈 , 难道真的要自己做一个这样的工具吗?真的是有点头大 。不过想想也挺有意思的 。至此 , 我萌生了要开发一个媲美 uTools 的开源工具箱的念头 。
二、研发
开篇第一步 , 按照我之前的套路都是先取好名字先占个坑 。我是个 Dota 玩家 , 之前写了一本《从0开始可视化搭建》的小册 , 里面使用了 Dota 中一个英雄的名字 coco(船长) 。这次我取名的是 rubick 即 拉比克 。Rubick(拉比克) 也是 Dota 里面的英雄之一 , 其核心技能是插件化使用其他英雄的技能 , 用完即走 。非常符合本工具的设计理念 , 所以取名 Rubick 。
实现工具自由,开源的桌面工具箱
文章图片

文章图片
我的核心目标就是需要让 Rubick 支持插件化 , 解决前面提到的问题:每个人的工具箱不同软件体积暴增每增加一个工具就需要更新版本
其次 , 通过调研了解到团队内有些同学已经在使用 uTools 了 , 要想让他们从 uTools 上把插件零成本迁移到 Rubick 上 , 就必须实现 uTools 的部分 API 能力 , 以及插件的定义和写法也需要和 uTools 规范保持一致 。
2.1 开发者模式
插件开发需要和 Rubick 进行联调 , 所以 Rubick 需要支持开发者模式 , 帮助开发者更好的开发插件 。首先先建一个 plugin.json 用于描述插件的基础信息:{"pluginName": "测试插件","author": "muwoo","description": "我的第一个 rubick 插件","main": "index.html","version": "0.0.2","logo": "logo.png","name": "rubick-plugin-demo","gitUrl": "","features": [{"code": "hello","explain": "这是一个测试的插件","cmds":["hello222", "你好"]}],"preload": "preload.js"}
2.1.1 核心字段name 插件仓库名称pluginName 插件名称description 插件描述 , 简洁的说明这个插件的作用main 入口文件 , 如果没有定义入口文件 , 此插件将变成一个模版插件version 插件的版本 , 用于版本更新提示features 插件核心功能列表features.code 插件某个功能的识别码 , 可用于区分不同的功能features.cmds 通过哪些方式可以进入这个功能
2.1.2 示例
开发插件的方式是复制 plugin.json 进入到 Rubick 的搜索框 , 所以需要监听搜索框的 change 事件 , 用于读取当前剪切板复制的内容:onSearch ({ commit }, paylpad) {// 获取剪切板复制的文件路径const fileUrl = clipboard.read('public.file-url').replace('file://', '');// 如果是复制 plugin.json 文件if (fileUrl && value =http://www.sos110.com/show/12/221528/=='plugin.json') {// 读取 json 文件const config = JSON.parse(fs.readFileSync(fileUrl, 'utf-8'));// 生成插件配置const pluginConfig = {...config,// 记录 index.html 存方的路径sourceFile: path.join(fileUrl, `../${config.main || 'index.html'}`),id: uuidv4(),// 标记为开发者type: 'dev',// 读取 iconicon: 'image://' + path.join(fileUrl, `../${config.logo}`),// 标记是否是模板subType: (() => {if (config.main) {return ''}return 'template';})()};}}
到这里我们已经可以根据复制的 plugin.json 能获取到插件的最基础的信息 , 接下来就是需要展示搜索框: commit('commonUpdate', {options: [{name: '新建rubick开发插件',value: 'new-plugin',icon: 'https://xxx.com/img.png',desc: '新建rubick开发插件',click: (router) => {commit('commonUpdate', {showMain: true,selected: {key: 'plugin',name: '新建rubick开发插件'},current: ['dev'],});ipcRenderer.send('changeWindowSize-rubick', {height: getWindowHeight(),});router.push('/home/dev')}},{name: '复制路径',desc: '复制路径',value: 'copy-path',icon: 'https://xxx.com/img.png',click: () => {clipboard.writeText(fileUrl);commit('commonUpdate', {showMain: false,selected: null,options: [],});ipcRenderer.send('changeWindowSize-rubick', {height: getWindowHeight([]),});remote.Notification('Rubick 通知', { body: '复制成功' });}}]});