想用Electron做个小工具?这个或许是终极版

故事背景

之前在网上有看到很多小伙伴基于 electron 实现了非常多好用的桌面端工具,比如图床管理工具 PicGo,就专门做图床工具。也有一些其他的类似的小工具,比如 saladict-desktop 专门做沙拉翻译查词的桌面端应用,colorpicker 专做桌面端取色工具...

我们也参考了这些小工具的设计理念,尝试在公司内部做一款桌面端工具,解决网络抓包、代理、图床、性能测评等常见场景的使用问题。最后在推广的时候,遇到了一个比较严重的问题,就是很多小工具对特定用户来说并不需要。比如测试只需要使用网络抓包、代理的功能,其他功能并不关心。此时就需要设计一款桌面端应用,类似于 App Store 那样,用到什么下载安装什么即可。这就需要实现桌面端应用的插件化。

于是乎,我们看到了 uTools 是支持插件化的桌面端应用,但是前提是我们的插件必须发布到 uTools 插件市场,才能实现多端同步下载的功能,但是公司内部的工具库有些涉及到安全信息又无法发布到 uTools 插件中,所以我们特别渴望有一款类似于 uTools 的内部工具箱。

为了进一步提高开发工作效率,最近我们基于 electron 开发了一款媲美 uTools 的开源工具箱 rubick。该工具箱不仅仅开源,最重要的是可以使用 uTools 生态内所有开源插件!这将是巨大的能力,意味着 uTools 生态内所有插件可以无差异化使用到 rubick 中。

想用Electron做个小工具?这个或许是终极版

代码仓库:https://github.com/clouDr-f2e/rubick

插件化之旅

一开始想到做插件化,无非就是使用 electronwebview 能力,实现类似于原生内嵌h5那样的方式,h5 页面可以做独立发布,原生提供 nativaAPI 之间通过 jsBridge 来桥接调用原生的方法。这样实现并无问题,我们也尝试了做了一次。最终思路大概是:

electron webview 方式

1. electron 中使用 webview

<webview src="https://xxx.xx.com/index.html" preload="preload.js" />

2. 实现 bridge

// preload.js
window.rubickBridge = {
  sayHello() {
    console.log('hello world')
  }
}

3. 插件借助 bridge 调用 electron 的能力

<html>
 <body>
     <div>这是一个插件<div>
 </body>
 <script>
  window.rubickBridge.sayHello()
</script>
</html>

4. 通信

因为 proload.jselectronrenderer 进程的,所以如果需要使用部分 main 进程的能力,则需要使用通信机制:

// main process
ipcMain.on('msg-trigger', async (event, arg) => {
    const window = arg.winId ? BrowserWindow.fromId(arg.winId) : mainWindow
    const operators = arg.type.split('.');
    let fn = Api;
    operators.forEach((op) => {
      fn = fn[op];
    });
    const data = await fn(arg, window);
    event.sender.send(`msg-back-${arg.type}`, data);
});
  
// renderer process
ipcRenderer.send('msg-trigger', {
  type: 'getPath',
  name,
});
ipcRenderer.on(`msg-back-getPath`, (e, result) => {
  console.log(result)
});

为什么后来我们又放弃了这条路

上一篇:关于升级 electron 版本后,无法将网页的日志打印到本地的问题


下一篇:麒麟常见问题