electron热更新

该文章仅记录热更新实现,全量更新请参考官网:传送门

1.原理分析

1.1 热更新需要替换内容

electron-builder打包时,会按照package.json中build字段的配置进行打包,其中打包的目录为files字段,所以其实我们每次更新只需要将该部分的内容替换,不需要将整个包更新,可以减少150m左右的更新大小,同时node_modules中的文件一般情况下也是不需要更新的,整个根据项目大小,又可以减少一波大小

1.2 包内容解析

我们files字段中的文件最后会被electron-builder打包到一个名为app.asar的文件中,这个app.asar中包含了所有的内容,但其实我们仅需要将node_modules主进程文件(main.js)打包进app.asar,剩余内容放到其他地方,便于热更新替换

2.具体实现

2.1 package.json修改
第一步:将我们不需要打包进app.asar的文件从里面拿出来
"asar": true,
"asarUnpack": [
	"dist/electron/**/*",
    "!dist/electron/node_modules",
    "!dist/electron/main.js"
],

此处将asar直接设置成false也可以,但是这样不太安全,此处我们将需要的文件全部放入,并排除node_modulesnode_modules

第二步:增加一个热更新版本号,用于判断时候需要热更新
"hotVersion": "0.0.1"
第二步:在应用启动时判断是否需要进行热更新

这块代码不在此处贴了,我是通过接口实现,将本地的hotVersion传给后端,然后后端拿去判断后告诉我是否需要热更新

第三步:下载更新包,并且解压到需要的目录然后重启

当后端告诉我需要进行热更新时,我们就去将更新包下载下来

HotUpdate.js文件:

const { app } = require('electron')
const path = require('path')
const fs = require('fs')
const os = require('os')
const http = require('http')
const AdmZip = require('adm-zip')

const downLoadZip = () =>
  new Promise((resolve, reject) => {
    const tmpDir = os.tmpdir() // 电脑的缓存目录
    const filename = path.resolve(tmpDir, `update-${new Date().getTime()}.zip`)
    const file = fs.createWriteStream(filename)
    http.get('更改成自己的下载地址', res => {
      res.pipe(file)
      res.on('end', () => {
        resolve(filename)
      })
      res.on('error', err => {
        reject(err)
      })
    })
  })

const hotUpdate = () => {
  const appPath = app.getAppPath() // 该方法可以获取程序app.asar的目录
  const replacePath = path.resolve(appPath, '../app.asar.unpacked/dist/electron') // 通过path.resolve组装成我们需要的路径
  downLoadZip().then(filename => {
    const zip = new AdmZip(filename) // 该工具可以压缩和解压,具体请自己去查看
    zip.extractAllTo(replacePath, true)
    app.relaunch()
    app.exit()
  })
}

module.exports = {
  hotUpdate
}

main.js文件中

import { hotUpdate } from './HotUpdate'
ipcMain.on('hotUpdate', () => {
   hotUpdate()
})

该方法需要绑定到主进程,不能在渲染进程中使用,会造成程序崩毁,当需要更新时,直接在渲染进程中调用主进程的该方法即可

3.打包出自己需要的热更新文件

const AdmZip = require('adm-zip')

function createZip() {
  const zip = new AdmZip()
  zip.addLocalFolder('dist/electron', '', fileName => {
    // 文件夹需要这样判断,因为如果文件夹内部有文件,fileName会是一个完整路径
    if (fileName.indexOf('node_modules') > -1) {
      return false
    }
    // 文件放在该处
    return !['main.js'].includes(fileName)
  })
  zip.writeZip('dist/update.zip') // 输出路径
}

4.将打包出的文件放到下载地址

上一步和这一步其实可以和打包发布平台放一起,让运维写一个脚本即可自动完成

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值