Rubick 的 star 数破 1k 的心路历程

前几个月在 github 上开源了一款基于 electron 实现的工具箱:Rubick 。出发点是为了解决公司内部插件无法发布到 uTools 生态但又需要类似 uTools 那样的插件化能力。同时开源社区也希望了解当前社区内是否也有这样的诉求,或许可以帮助我们更好的完善和改进。在开源的过程中还是遇到了不少问题和挑战,谨以此文记录与 Rubick 有关的我的心路历程。

项目体验安装

github 项目地址:Rubick

工具下载链接:下载体验

demo

项目孵化

启蒙

Electron 是 GitHub 开源的一个框架。它通过 Node.js 和 Chromium 的渲染引擎完成跨平台的桌面 GUI 应用程序的开发。我起初没有接触过 Electron,最开始接触 electron 是因为看到了 PicGo 作者在掘金上推广他的图床工具。他的一个核心功能非常吸引我,就是 macos 下可以直接拖拽图片进入任务托盘上传图片:

image.png

当时正好我们团队也需要搞一个内部的 cdn 图片资源管理图床,用于项目图片资源压缩并直接上传到 cdn 上,之前我们做了个网页版。而这里我深刻的感受到了 electron 的强大,可以极大的提高工作效率,参考 PicGo,我尝试做了第一个 electron 项目,完成了基于 tinypng 的图片压缩上传到内部 cdn 的桌面端应用。

演化

之后公司内部因为开发需要,需要和后端进行接口联调,测试环境的时候,经常会涉及到一些状态改变要看交互样式的问题。比如测试需要测商品的待支付、支付中、支付完成等各种节点的交互样式是否符合预期,这种情况测试一般会去造数据或者让后端改数据库接口。有的小伙伴可能会用 Charles 修改返回数据进行测试。但是 Charles 的抓包体验和配置体验感觉有点麻烦,对新人不是很友好,所以我们自己做了个非常易用 抓包&mock 工具:

抓包

这也是 Rubick 最早的雏形。 随后,我们发现,当页面发布线上的时候,没有办法在微信环境内对线上页面进行调试,所以开发了一个基于 winner 的远程调试功能:

image.png

随着 Rubick 在内部不断推广和使用,所需功能也越来越多。我们需要 需求管理一键VPN性能评估埋点检测 等等工具。这些工具的增加一方面导致我们的 Rubick 体积暴增,一方面又导致了用户需要不断更新软件,导致用户体验非常差。

其次,我们在推广给测试、UI同学使用的时候,发现他们其实并不关注前面的页面调试、性能测评等功能,可能只是用到其中某一项,所以整个项目对他们来说就显得很臃肿。

灵感

直到有一天,我在掘金上看到这样一个沸点:

image.png

下面有个评论提到了 uTools 这是我第一次和 uTools 产生了交集,在体验了 uTools 功能后,我长吸一口气:这不就是我想要的嘛!然后就去 GitHub 上找 uTools 的源码,发现它并没有开源。

所以就想把上面提到的那些工具, 发布到 uTools 市场在 uTools 里通过插件的方式使用他们。但我发现发布插件只能发布到公网,但这又涉及到数据安全的问题。

无奈,难道真的要自己做一个这样的工具吗?真的是有点头大。不过想想也挺有意思的。至此,我萌生了要开发一个媲美 uTools 的开源工具箱的念头。

研发

开篇第一步,按照我之前的套路都是先取好名字先占个坑,之前写了一本《从0开始可视化搭建》的小册,里面基于 dota 取了个 coco 的名字。这次我取名的是 rubick拉比克。Rubick(拉比克) 是 dota 里面的英雄之一,其核心技能是插件化使用其他英雄的技能,用完即走。非常符合本工具的设计理念,所以取名 Rubick

image.png

支持插件化

我们的核心目标就是需要让 Rubick 支持插件化,解决前面提到的问题。当复制 plugin.json 进入搜索框时,变可直接出现 2个选项,一个新建插件,一个复制路径的功能:

image.png

运行插件

运行插件是比较有意思的一个环节,接下来我会稍微介绍一下实现原理:

运行插件需要容器,electron 提供了一个 webview 的容器来加载外部网页。所以我们可以借助 webview 的能力实现动态网页渲染,这里所谓的网页就是插件。但是网页无法使用node的能力,而且我们做插件的目的就是为了开放与约束,需要对插件开放一些内置的 API 能力。好在 webview 提供了一个 preload 的能力,可以在页面加载的时候去预置一个脚本来执行。

也就是说我们可以给自己的插件写一个 preload.js 来加载。但这里需要注意我们既要保持插件的个性又得向插件内注入全局 API 供插件使用,所以可以直接加载 rubick 内置 preload.jspreload.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'));
复制代码

到这里就已经实现了一个最基础的插件加载,我们来看看效果:

image.png

支持更多体验能力

随后为了更加贴近 uTools 的体验,我又开始着手让 Rubick 支持更多原生体验增强的特性:超级面板、模板、系统命令、全局快捷键等

超级面板

长按鼠标右键,即可呼起超级面板,可以根据当前鼠标选择内容,匹配对应插件能力。比如当前选择图片后长按右击,则会呼起上传图床插件:

image.png

模板

为了更贴合 uTools 的插件能力,需要实现模板功能,模板即是一个内置 UI 样式的功能插件。

系统命令

取色

基于 robot.js 以及 iohook 实现。未使用 C++ 扩展。输入框内输入 取色 或者 colorpocker 唤起

image

截屏

输入框内输入 shortcut 或者 截屏 唤起

全局快捷键

最后

再次致敬 uTools!如果没有它就没有 Rubick,我做 Rubick 旨在技术分享,并不以商业化为目的。

以上就是我和 Rubick 的故事,如果 Rubick 对您有帮助,那么就请给个 Star ✨ 鼓励一下:

github.com/clouDr-f2e/…


机缘巧合我发现了 HelloGitHub 一个推荐开源项目的平台,了解到卤蛋也是喜欢打 Dota,我想那他应该能感受到 Rubick 的魅力,所以我就抱着试一试的心态投稿了。也有幸入选了月刊第 64 期

最后,感谢 HelloGitHub 让 Rubick 被更多人发现和喜欢,特别感谢卤蛋对文章的润色和修改,让本文增色不少。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享