V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
cococoder
V2EX  ›  程序员

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

  •  
  •   cococoder · Mar 23, 2024 · 3475 views
    This topic created in 766 days ago, the information mentioned may be changed or developed.

    预期

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

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

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

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

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

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

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

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

    或者不使用 asar 打包,下载压缩包直接解压替换
    CCidea
        19
    CCidea  
       Mar 24, 2024
    能不重启的方案目前可以说是没有,热更新一直是一个很大的问题,方案倒是有很多,就是没有一个完美的
    cococoder
        20
    cococoder  
    OP
       Mar 24, 2024
    @subframe75361 主进程代码不太好全部打包,electron-builder 官方说明过,node_modules 中可能会有 native_modules ,一般不建议打包到 asar ,既然你那边已经实现了通过 app.asar 加载 name.asar ,应该还可以扩展下,可以不仅仅局限于 asar 文件,也可以加载其他文件如原生模块等,不知道是否可行?
    flyqie
        21
    flyqie  
       Mar 24, 2024 via Android
    好奇这种的需求是啥,大屏吗?大屏也可以自动重新拉起吧?
    subframe75361
        22
    subframe75361  
       Mar 24, 2024   ❤️ 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
       Mar 24, 2024
    @subframe75361 感谢解答,研究了一下你的库,依然有几个问题:
    1. 目前这个库的实现方案和直接下载 app.asar 文件然后替换有什么区别?侧重于解决什么问题

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

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