在一切开始之前,首先要致敬 uTools!如果没有它就没有 Rubick。
我做的 Rubick 是一款基于 Electron 的开源桌面工具箱,简单讲就是好多工具的集合,然后加上快速启动、丰富的插件扩展等功能于一体。
没错!它的使用方式和外观几乎和 uTools 一摸一样。那我为什么放着免费的 uTools 不用,非要自己搞一个呢?
事情的起因是这样的,出于安全方面的考虑有一些仅适用于公司内部的插件不能发布到插件市场,所以不能接入 uTools。但实在眼馋 uTools 式的便捷、用完即走的极简操作体验。在搜寻解决方案无果,同时也发现其他的小伙伴也有同样的诉求,所以我动手做了,然后把它开源了。
Rubick 一款呼出超快、用完即走的开源工具箱,因为开源所以更自由!
项目地址:https://github.com/clouDr-f2e/rubick
希望它能帮助你解决同样的烦恼,但目前仅支持 Windows 和 macOS,Linux 版本正在开发中。想借助开源的力量让 Rubick 变强,成为金牌辅助!帮助大家轻松“超神”!
在做 Rubick 的过程中还是遇到了不少问题和挑战,下面就分享下我的心路历程。
Electron 是 GitHub 开源的一个框架。它通过 Node.js 和 Chromium 的渲染引擎完成跨平台的桌面 GUI 应用程序的开发。我起初没有接触过 Electron,最开始接触它是因为看到了 PicGo 的一个核心功能非常吸引我,就是 macOS 下可以直接拖拽图片进入任务托盘上传图片:
当时正好我们团队也需要搞一个内部的 CDN 图片资源管理图床,用于项目图片资源压缩并直接上传到 CDN 上,之前我们做了个网页版。而这里我深刻的感受到了 Electron 的强大,可以极大的提高工作效率,参考 PicGo 我尝试做了第一个 Electron 项目,完成了图片压缩上传到内部 CDN 的桌面端应用。
之后公司内部因为开发和后端进行接口联调测试环境时,经常会涉及到一些状态改变要看交互样式的问题。比如测试需要测商品的待支付、支付中、支付完成等各种节点的交互样式是否符合预期,这种情况测试一般会去造数据或者让后端改数据库接口。有的小伙伴可能会用 Charles 修改返回数据进行测试,但 Charles 的抓包体验和配置体验感觉有点麻烦,对新人不是很友好所以我们自己做了个非常易用 抓包&mock 工具:
这也是 Rubick 最早的雏形。随后,我们发现当页面发布线上的时候,没有办法在微信环境内对线上页面进行调试,所以开发了一个基于 winner 的远程调试功能。
但随着该 Rubick 在内部不断推广和使用,所需功能也越来越多。我们需要 需求管理、性能评估、埋点检测 等等工具。这些工具的增加一方面导致 Rubick 体积暴增,一方面又导致了用户需要不断更新软件,导致用户体验非常差。
其次,我们在推广给测试、UI 同学使用的时候,发现他们其实并不关注前面的页面调试、性能测评等功能,可能只是用到其中某一项,所以整个项目对他们来说就显得很臃肿。
直到有一天,我在掘金上看到这样一个沸点:
下面有个评论提到了 uTools 这是我第一次和 uTools 产生了交集,在体验了 uTools 功能后,我长吸一口气:这不就是我想要的嘛!然后就去 GitHub 上找 uTools 的源码,发现它并没有开源。
所以就想把上面提到的那些工具, 发布到 uTools 市场在 uTools 里通过插件的方式使用他们。但我发现发布插件只能发布到公网,但这又涉及到数据安全的问题。
无奈,难道真的要自己做一个这样的工具吗?真的是有点头大。不过想想也挺有意思的。至此,我萌生了要开发一个媲美 uTools 的开源工具箱的念头。
开篇第一步,按照我之前的套路都是先取好名字先占个坑。我是个 Dota 玩家,之前写了一本《从0开始可视化搭建》的小册,里面使用了 Dota 中一个英雄的名字 coco(船长)。这次我取名的是 rubick 即 拉比克。Rubick(拉比克) 也是 Dota 里面的英雄之一,其核心技能是插件化使用其他英雄的技能,用完即走。非常符合本工具的设计理念,所以取名 Rubick。
我的核心目标就是需要让 Rubick 支持插件化,解决前面提到的问题:
其次,通过调研了解到团队内有些同学已经在使用 uTools 了,要想让他们从 uTools 上把插件零成本迁移到 Rubick 上,就必须实现 uTools 的部分 API 能力,以及插件的定义和写法也需要和 uTools 规范保持一致。
插件开发需要和 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"
}
name
插件仓库名称pluginName
插件名称description
插件描述,简洁的说明这个插件的作用main
入口文件,如果没有定义入口文件,此插件将变成一个模版插件version
插件的版本,用于版本更新提示features
插件核心功能列表features.code
插件某个功能的识别码,可用于区分不同的功能features.cmds
通过哪些方式可以进入这个功能开发插件的方式是复制 plugin.json
进入到 Rubick 的搜索框,所以需要监听搜索框的 change
事件,用于读取当前剪切板复制的内容:
onSearch ({ commit }, paylpad) {
// 获取剪切板复制的文件路径
const fileUrl = clipboard.read('public.file-url').replace('file://', '');
// 如果是复制 plugin.json 文件
if (fileUrl && value === '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',
// 读取 icon
icon: '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: '复制成功' });
}
}
]
});
到这里,当复制 plugin.json
进入搜索框时,便可直接出现 2 个选项,一个新建插件,一个复制路径的功能:
当点击 新建 rubick 插件
功能时,则需要跳转到 home
页,加载插件的基础内容,唯一需要注意的是 home
页加载的内容高度应该是 Rubick 最大窗口的高度。所以需要调整窗口大小:
ipcRenderer.send('changeWindowSize-rubick', {
height: getWindowHeight(),
});
关于 renderer
里面的 Vue 代码这里就不再详细介绍了,因为大多是 css 画一下就好了,直接来看展示界面:
到这里,就完成了开发者模式,接下来再聊聊插件是如何在 Rubick 中跑起来的。
运行插件需要容器 Electron 提供了一个 webview
的容器来加载外部网页。所以可以借助 webview
的能力实现动态网页渲染,这里所谓的网页就是插件。但是网页无法使用 node 的能力,而且做插件的目的就是为了开放与约束,需要对插件开放一些内置的 API 能力。好在 webview
提供了一个 preload
的能力,可以在页面加载的时候去预置一个脚本来执行。
也就是说可以给自己的插件写一个 preload.js
来加载。但这里需要注意既要保持插件的个性又得向插件内注入全局 API
供插件使用,所以可以直接加载 Rubick 内置 preload.js
,在 preload.js
内再加载个性化的 preload.js
:
// webview plugin.vue
<webview id="webview" :src="path" :preload="preload"></webview>
<script>
export default {
name: "index.vue",
data() {
return {
path: `File://${this.$route.query.sourceFile}`,
// 加载当前 static 目录中的 preload.js
preload: `File://${path.join(__static, './preload.js')}`,
webview: null,
query: this.$route.query,
config: {},
}
}
}
</script>
对于 preload.js
就可以这么用啦:
if (location.href.indexOf('targetFile') > -1) {
filePath = decodeURIComponent(getQueryVariable('targetFile'));
} else {
filePath = location.pathname.replace('file://', '');
}
window.utools = {
// utools 所有的 api 实现
}
// 加载插件 preload.js
require(path.join(filePath, '../preload.js'));
到这里就已经实现了一个最基础的插件加载,效果如下:
随后为了更加贴近 uTools 的体验,我又开始着手让 Rubick 支持更多原生体验增强的特性:超级面板、模板、系统命令、全局快捷键等
再次致敬 uTools!我做 Rubick 旨在技术分享,并不以商业化为目的。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/LFSSv1hQGBepyYVhlKhVjQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。