V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cococoder
V2EX  ›  程序员

electron 中有没有什么成熟的热更新的方案?

  •  
  •   cococoder · 243 天前 · 2200 次点击
    这是一个创建于 243 天前的主题,其中的信息可能已经有所发展或是发生改变。

    预期

    1. 实现 asar 文件以及其他 app.asar.unpack 文件的更新,目前在 git 上找到过几个库,基本是基于 asar 文件的更新,而且 star 很少,不是完全符合我的预期

    2. 最好是能不重启,实现真正意义上的热更,万一有什么野路子呢

    3. 是否知道有那些应用有过类似的方案,可以借鉴一下的

    27 条回复    2024-03-25 11:57:42 +08:00
    anUglyDog
        1
    anUglyDog  
       243 天前
    除了浏览器用不了的系统 API ,全部资源走 web ?
    cococoder
        2
    cococoder  
    OP
       243 天前
    目前全部走的本地文件,走 web 和现有的架构不符合,改造成本大
    cococoder
        3
    cococoder  
    OP
       243 天前
    @anUglyDog 1. 成本大,改造起来不太现实 2. 系统 api 相关的调用更新不了,打包的内容中含有 node_modules ,不完全符合预期
    lisongeee
        4
    lisongeee  
       243 天前
    我想知道你现在用的 electron 内部运行是 esm 还是 cjs ?

    如果是 esm ,esm 貌似无法删除模块缓存对象 <https://github.com/nodejs/help/issues/1399>

    此种类型热更新在极端情况下不重启会让内存占用越来越大
    drymonfidelia
        5
    drymonfidelia  
       243 天前
    @cococoder 系统 api 相关的调用更新不了 直接把系统 api 全部暴露给线上网页 虽然很不安全,但你搞的自动更新也没差,都是直接执行互联网上的代码
    subframe75361
        6
    subframe75361  
       243 天前
    写过一个参考 obsidian 的库,也是类似替换 asar 的,但是通过多个 asar 包实现:app.asar 加载 name.asar ,下载新的 name.asar 后重启替换。https://github.com/subframe7536/electron-incremental-update
    subframe75361
        7
    subframe75361  
       243 天前
    目前用过的有热更新的应用只有一个 obsidian

    如果只是热更新渲染进程的话可以把渲染进程的代码额外打一个 asar ,主进程控制窗体重载
    如果需要热更新主进程的话,除了重启没找到能实现的方法
    subframe75361
        8
    subframe75361  
       243 天前
    还有一种思路,开启 web worker 的 node 集成,把主进程的业务代码移到 web worker 里面,ipc 接口改造成 message 通信,这样只需要热更新渲染进程即可
    xiangyuecn
        9
    xiangyuecn  
       243 天前
    eval + location.reload() 完事
    cococoder
        10
    cococoder  
    OP
       243 天前
    @lisongeee 了解了,我们 node 部分是 cjs ,前端部分是 esm
    cococoder
        11
    cococoder  
    OP
       243 天前
    @subframe75361 好吧,目前看主进程确实麻烦些 不重启不行,渲染进程重载其实也挺麻烦,需要通知其他窗口更新,还不如直接重启省事,之前做 i18n 语言切换考虑过这种(参考 slack ),窗口太多的话,也是个麻烦事,可能还会影响性能
    cococoder
        12
    cococoder  
    OP
       243 天前
    @subframe75361 感谢。我研究研究
    cococoder
        13
    cococoder  
    OP
       243 天前
    @drymonfidelia 线上网页安全问题可能更大些,线上页面要是被攻击,就会导致客户客户端被远程调用的风险,毕竟客户端本地 file://文件要被攻击,得先攻击用户电脑
    cococoder
        14
    cococoder  
    OP
       243 天前
    @xiangyuecn 主进程的代码 eval?如何动态加载到代码并 eval?如果是 eval 就不能打包成 asar 了
    drymonfidelia
        15
    drymonfidelia  
       243 天前
    @cococoder 你做成无感更新,我推个恶意更新下去,也能远程调用
    cococoder
        16
    cococoder  
    OP
       243 天前
    @subframe75361 看了一下你的库,看着应该是 name.asar 是动态更新的内容,app.asar 属于一个启动器,用来加载其他模块,app.asar 一开始就需要把部分主进程代码以及原生代码( node_modules ),这样是不是就意味 node_modules 没法实现更新?并且这样的更新是有限制的,如果 name.asar 中新增一个 node 依赖但是 app.asar 中不存在,这样就会出问题?
    cococoder
        17
    cococoder  
    OP
       243 天前
    @drymonfidelia 这个都是相对而言,推恶意更新下去,这个更多是测试和审核的锅,就像你非要在你代码里下毒是一个道理
    subframe75361
        18
    subframe75361  
       242 天前
    @cococoder #16
    webpack 不清楚,如果使用 vite 构建,可以全打包好,不需要 node_modules

    至于 native modules ,应该全部放在 app.asar 里,只能通过完整安装包更新

    或者不使用 asar 打包,下载压缩包直接解压替换
    CCidea
        19
    CCidea  
       242 天前
    能不重启的方案目前可以说是没有,热更新一直是一个很大的问题,方案倒是有很多,就是没有一个完美的
    cococoder
        20
    cococoder  
    OP
       242 天前
    @subframe75361 主进程代码不太好全部打包,electron-builder 官方说明过,node_modules 中可能会有 native_modules ,一般不建议打包到 asar ,既然你那边已经实现了通过 app.asar 加载 name.asar ,应该还可以扩展下,可以不仅仅局限于 asar 文件,也可以加载其他文件如原生模块等,不知道是否可行?
    flyqie
        21
    flyqie  
       242 天前 via Android
    好奇这种的需求是啥,大屏吗?大屏也可以自动重新拉起吧?
    subframe75361
        22
    subframe75361  
       242 天前   ❤️ 1
    @cococoder #20
    关于打包你可以看一下这个 https://github.com/electron-vite/vite-plugin-electron-renderer?tab=readme-ov-file#dependency-pre-bundling

    我自己的 side project 实测 better-sqlite3 和 napi-rs 相关的库是可以打包的,其他的暂时没有需求就没有测试过。至于加载其他的模块,可以直接调用 app.asar 里的 js 函数,我的库也提供了简化的加载方法

    cococoder
        23
    cococoder  
    OP
       242 天前
    @subframe75361 感谢解答,研究了一下你的库,依然有几个问题:
    1. 目前这个库的实现方案和直接下载 app.asar 文件然后替换有什么区别?侧重于解决什么问题

    2. 可能是之前没用过 vite-plugin-electron ,目前是看 vite-plugin-electron 是有点强耦合的,我理解 vite-plugin-electron 这个库 vite 和 electron 结合更多是方便本地开发,和你的更新相关的功能关系不大

    3. 是否有个简单的 demo 能跑起来的
    cococoder
        24
    cococoder  
    OP
       242 天前
    @flyqie 热更需求挺常见的吧,比如 hot fix ,这里主要是『不重启』为了不影响用户体验,有些更新能无感尽量无感
    subframe75361
        25
    subframe75361  
       242 天前
    @cococoder #23
    1. 直接替换 asar 文件需要额外的可执行文件进行覆盖和重启,并且原生模块也需要放进更新包里,增大体积的同时还会添加其他平台的依赖(当然可以通过构建不同平台的更新包解决)。我认为原生模块的热更新需求肯定远小于其他模块,所以我觉得把原生模块放到 app.asar 里,其他代码放到另外一个 asar 里加载比较合理(而且减小体积的同时只需要打一个包)
    2. 是的,这个库其实是对 Obsidian 热更新策略的开源实现+用于构建的 vite 插件,提供一种实现思路。选用 vite 也只是因为自己在用的时候遇到了一些通用的问题(比如说冗余的 node_modules ),就写了个库出来。
    3. 本地有一个,有空整理上传一下
    cococoder
        26
    cococoder  
    OP
       241 天前
    @subframe75361 关于第一点,目前我了解到的直接替换 asar 文件在 mac 上是不需要额外的可执行文件的,windows 上不确定。难得遇到一个在 electron 更新上了解比较深的,不知道是否可以加个联系方式,后面一起交流下,vx: c2hhZG93X0xCSg==
    subframe75361
        27
    subframe75361  
       241 天前 via Android
    @cococoder #26 我看过的所有热更新的文章里都是要用 exe 启动更新进程的,应该是 windows 机制,自己也没有尝试过。至于了解,其实我也只有一个 sideproject 的经验😂
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1277 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:32 · PVG 07:32 · LAX 15:32 · JFK 18:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.