五一期间花时间学习了一下 electron,基本算是入门吧
学习的目的是为了解决跨平台桌面应用的开发问题,虽然也算熟悉 Qt,但是相对目前日新月异的新技术来说,有点太“经典”了
所以考虑用 electron 来做跨平台桌面应用开发,我的想法是拿 electron 做前端,再用 golang 写个后端,负责一些比较底层,或者对运行效率要求比较高,抑或是有保密需求的工作。electron 和 golang 的跨平台都非常容易实现,这样就可以比较完美的实现这个需求。
一开始我把后端放在服务器上,但是就要求使用者必须要联网才能使用,这个有些麻烦。后来找到 child_process, 于是可以把可执行程序直接放在程序包中,然后 spawn 出后端程序,再进行进程间通讯即可
目前有几个问题想请教一下各位大佬:
有大佬尝试过这种组合吗?有没有什么坑?为什么没怎么看到有人这么搞?
从 electron 启动后端程序,可以放在 app.ready 事件中,但是程序退出时需要自动关闭后端,放在哪个事件比较合适?因为我看到 before-quit, will-quit, quit 这三个事件,都标注了
Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
而 window-all-closed 事件,又说
If the user pressed Cmd + Q, or the developer called app.quit(), Electron will first try to close all the windows and then emit the will-quit event, and in this case the window-all-closed event would not be emitted.
那么到底放在哪个事件里更合适呢?
进程间通讯我用 HTTP 接口,一个原因是开发方便,另一个原因是做成 web 也可以通用,但是这里存在一个后端绑定哪个端口的问题,我想了两个方案:
不知道还有没有更好的方法?
1 HuHui 2020-05-05 11:53:00 +08:00 via Android 可以再看看 therecipe/qt |
2 teawithlife OP @HuHui #1 这个用到了 cgo 吧? cgo 的交叉编译有些麻烦 |
![]() | 3 SingeeKing PRO 我个人不喜欢 electron 的两大原因是体积大和启动慢,这个似乎优化的点在执行效率 |
4 Jirajine 2020-05-05 12:33:05 +08:00 via Android 有一个 go 的 electron 绑定 https://github.com/asticode/go-astilectron 但看起来不太成熟。 至于你说的起一个后台服务然后 IPC 交互我一个自己用的小玩意就是这么搞的,除了有点套娃没发现什么坑,也没考虑那么多直接 quit 完事。端口直接随机一个然后参数传过去。 这样做好处就是天然支持后端远程运行,不然还不如传统的 native 扩展方便,或者 wasm 也不错。 |
![]() | 5 pkwenda 2020-05-05 12:39:35 +08:00 刚想发就被楼上发了,electron 很重的 。 |
6 teawithlife OP @SingeeKing #3 体积大显得有份量,有工作量(:P ),启动慢这个确实有点不好,不过现在按现在的平均硬件水平,已经勉强可以接受了。主要优化的点在于 js 我不熟(手动狗头) |
7 teawithlife OP @Jirajine #4 感谢推荐,这个库看起来还不错,我好好看看 你随机一个端口,得先 listen 一下,确定端口没被占用,然后才能传给后端吧?我刚才又想了一个方案,前端可以自己 listen 一个端口 A,然后作为参数传给后端,后端随机 listen 一个端口 B,然后通过端口 A 告知前端。这样虽然有点绕,但是可靠性高,而且确保跨平台 wasm 还是再等等吧,目前还不算成熟 |
![]() | 8 SingeeKing PRO @teawithlife #6 这不是简单的「有份量」「勉强可以接受」,electron 大的问题在于无论再小的应用都打包了一个环境进去,而一般个人电脑启动最快也要 1-2 秒,这些在一起就真的对 electron 难以有好感 |
![]() | 9 murmur 2020-05-05 13:02:49 +08:00 electron 目前看到比较成功的应用就是 vscode 了,其余的都不是严格的 electron,尤其是国产那堆软件,你看着是 chrome 套壳,背后辣么一大堆 dll 都不知道干啥的 |
![]() | 10 jason94 2020-05-05 13:29:15 +08:00 1. 之前看到这篇 https://wiredcraft.com/blog/high-security-electron-js-application/,也想这么搞,后来感觉有点麻烦,主要就是不好维护。保密这块可以考虑 js 源码 转字节码(目前在几十万用户运行没问题) 2. before-quit 或 will-quit 。如果窗口关闭之前不做操作的话,可以丢 before-quit 里 3. 方案一可以用这个库 https://www.npmjs.com/package/portfinder |
![]() | 11 ysc3839 2020-05-05 13:42:00 +08:00 via Android 不然考虑 Golang + Cef ? https://github.com/CzarekTomczak/cef2go |
12 teawithlife OP @SingeeKing #8 这个话题记得之前 V2 也有几个主题讨论过,我部分赞同你的观点,对于一个有追求的程序员来说,体积大执行慢确实难以忍受,但同时我认为这是为了实现跨平台所要付出的代价,其实 Qt,golang 都是这么一个套路,把整个 runtime 都打包了(当然他们没 electron 那么臃肿)。所以,算是有舍有得吧,就看你以及你的最终用户看重啥了 |
13 teawithlife OP @jason94 #10 保密是其中一个原因吧,主要还是我作为 crud boy,对前端只停留在 ctrl+c/v 程序员的程度,所以需要把大部分逻辑工作放到后端来实现 你说的 portfinder 库我看过源码,就是我说的遍历尝试 listen 的方法,这种方法存在一个极小概率的 race condition,可能前端检查的时候,这个端口是可用的,但是等到后端调用时,这个端口已经被其他进程抢先占用了(虽然概率极低,但这确实是可预见的风险) |
14 teawithlife OP ![]() @ysc3839 #11 这个库的 commit 记录,从 2014 年之后的记录,都是在改 README 了,不敢用。。。 |
15 Jirajine 2020-05-05 14:10:24 +08:00 via Android @teawithlife 被占了启动服务会绑定失败,js 处理下错误重新随机一个再次启动,这个几率本身也很小,或者用楼上提到的库。 wasm 毕竟是未来,高性能扩展不用再包装一堆丑陋的 C 接口了。 |
16 teawithlife OP @Jirajine #15 对哦,启动不起来换个端口再来一遍就行了,我咋把这个办法给忘了 |
17 optional 2020-05-05 14:39:05 +08:00 wasm 不二选择啊。 |
18 kuyuzhiqi 2020-05-05 19:03:28 +08:00 可以的,不难,不同的平台运行时把 go 的运行环境带上,electron 那边启动 go 的服务就行 |
19 teawithlife OP 从下午到晚上都在研究打包的问题,增加一些额外的信息给需要的朋友: 1. 目前打包的工具有两个 electron-builder 和 electron-packager,用 electron-vue 建立项目时,可以选择其一作为打包工具 2. electron-builder 功能较全,配置比较麻烦,除了打包之外,可以制作各种安装包,electron-packager 比较简单易用。我测试了用 electron-packager 在 linux 平台生成 linux 和 windows 的可执行程序,如果要生成 windows 平台程序,需要先自行装 wine (据说是为了改图标),也测试了用 electron-builder 在 linux 平台生成 windows 下的可执行程序和安装程序,没有需要自己安装的工具,生成的过程会自动下载(不清楚是否需要 wine,因为已经装过了),其他的平台就没测试了(注意,为了确保下载成功,请科学上网) 3. 两个工具在打包的时候都可以设置一个 asar 参数,如果为 true,会把整个 app 打包为一个 asar 文件,这样据说可以提高 IO 效率(特别是在 windows 下),由于程序较小,没有明显感觉,但是在复制的时候有明显区别,因为不打包的话,node_modules 这个文件夹得复制半天 4. 如果启用 asar 文件,在 child_process 里面的函数,exec, fork, spawn 全部都不能用,只能用 execFile,如果确实想用,可以将需要执行的文件,从 asar 文件中复制出来 5. 我把后端程序放到了 static 文件夹中,发现打包之后,`dist/static/`文件夹虽然已经有了程序,但是文件属性从 755 变成 644 了,原因是 electron-vue 的打包脚本中,复制 static 文件夹时,用的是 copy-webpack-plugin,它这个 issue 至今未解决。我最后没办法,直接修改 build.js 文件,复制完成之后,手动执行一次`chmod +x`,把权限改回来 |
20 qwe121002 2020-05-06 02:23:01 +08:00 via Android 有人会做 h5 跳转转账的付款模式吗 |
21 teawithlife OP @qwe121002 #20 提问的话,最好单独发一个主题,尽量描述清楚你的目的和已经做了哪些尝试,这样会有更多的人帮助你 |
22 buffzty 2020-05-06 14:06:21 +08:00 我的想法跟你一样. 桌面软件用 electron+tsx 做前端展示. 大部分功能用 node 写, 再用 go 起一个 http 服务器 做一些本来需要用 c 完成的功能. |
23 teawithlife OP @buffzty #22 对的,就是这么个思路。那你在实际使用过程中,有碰到什么问题吗? |
24 buffzty 2020-05-06 15:34:09 +08:00 @teawithlife 还没写过 pc 端项目,我们现在全部都是 web. 前端 tsx, 后端 go .我觉得套个 electron 应该问题不大 |
25 teawithlife OP @buffzty #24 作为业余前端,我的操作是找个 vue+element-ui 模板改一改,搞定显示的内容,所有的逻辑放到后端来实现 |
26 qwe121002 2020-05-08 00:35:35 +08:00 via Android |
![]() | 27 zkdfbb 2020-07-17 00:05:37 +08:00 @teawithlife 这两天也跑了个 demo,发现了一个很奇怪的问题,使用 asar: true 打包时,child_process 里面的函数,exec, fork, spawn 是可以用的,但是遇到一个很奇怪的问题,使用 go 编译出来一个后台程序,然后通过 electron 来启动它。无论是用 spawn 还是 exec,打包出来的程序在 mac 平台下是可以正常启动的,但是在 windows 下面怎么都启动不了,一启动就退出,exit code 是 1,问题是这个 go 编译出来的程序单独打开是正常的,说明不是程序的问题,而且用一段最简单的程序,比如直接 time.Sleep 一段时间,用 spawn 启动也是马上就退出了。但是用 spawn 启动一个其他的程序,比如 dir,python -m http.server 又都是正常的。崩溃了。。。 |
28 teawithlife OP @zkdfbb #27 exec, fork, spawn 在启用 asar 时不能使用,我是看文档里面这么写的,倒确实没试过,也可能是操作系统相关。 你在 windows 平台用 execFile 可以启动这个 go 程序吗? 进程的启动,不同操作系统的实现区别会比较大,可能有些情况不太好兼容 |
![]() | 29 zkdfbb 2020-07-17 10:32:11 +08:00 @teawithlife execFile 也试过了,就是很奇怪,其他的比如 python -m http.server 都 OK,偏偏 go 程序就不行 |
![]() | 30 AndyAO 2021-01-09 08:51:39 +08:00 思源笔记是这种结构 前端 Javascript(Electron),后端 Go |
31 dosgo 2021-09-13 23:16:14 +08:00 挑来跳去,还是 electron 好用,fyne 实在是丑,然后好多复杂功能不好弄,而且官方理念我就看的无语。。。跨平台 GUI 这套目前 electron 最优,毕竟跨平台的 GUI 库投入太大很少公司开发。。。 |
![]() | 32 lizhenda 2022-06-23 14:52:30 +08:00 思路不错,准备这么干,但有个疑问。我直接已 nodejs 来写后台服务和用 Go 来写有什么优劣呢。感觉 nodejs 直接在 electron 的主进程启动更加方便,但 go 的话性能更好,可以直接放在云上,不止是个本地服务了。纠结。 |
33 teawithlife OP @lizhenda #32 我个人是熟悉 go ,前端只是半吊子,所以选择用 go ,如果你熟悉 js 的话,用 nodejs 也是可以的,至于放到云上运行的需求,套个 docker 就可以了,还有性能问题,不必过早考虑,先把业务跑起来再说,等日活上来了,再考虑优化也不迟 |
34 qqshenhan 2023-11-15 12:25:02 +08:00 @teawithlife 楼主觉得 wails 怎么样 |