五一期间花时间学习了一下 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 2020-05-05 12:29:31 +08:00 via iPhone
我个人不喜欢 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 2020-05-05 12:51:49 +08:00
@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 364 天前
@teawithlife 楼主觉得 wails 怎么样
|