Electron 自动更新完整实现(全量更新 vs 增量更新 )

Electron 自动更新完整实现(全量更新 vs 增量更新)

本篇文章基于 electron-vite-vue 脚手架,完整展示 Electron 自动更新的两种实现方案:

  • 方案一:全量更新(默认,适合首次发布或大版本)
  • 方案二 :增量更新(基于 .blockmap,适合小版本快速发布)

每种方案将从构建配置、更新流程、代码实现三个维度细化讲解。


🧱 统一前置依赖安装

bash 复制代码
npm install electron-updater electron-log

📁 目录结构推荐

复制代码
electron-vite-vue/
├── electron/
│   ├── main/
│   │   └── updater.ts
│   └── preload/
│       └── index.ts
├── src/
│   ├── App.vue
├── package.json

✅ 方案一:全量更新(默认)

📦 构建配置(package.json)

json 复制代码
"build": {
  "appId": "com.example.myapp",
  "productName": "MyApp",
  "win": {
    "target": "nsis"
  },
  "publish": {
    "provider": "github",
    "owner": "your-github",
    "repo": "your-repo"
  }
}

🛠 发布文件(上传到 GitHub Releases)

  • MyApp Setup 1.0.0.exe
  • latest.yml

🔧 主进程更新逻辑(updater.ts)

ts 复制代码
import { autoUpdater } from 'electron-updater'
import { BrowserWindow, ipcMain } from 'electron'
import log from 'electron-log'

export function setupAutoUpdater(win: BrowserWindow) {
  autoUpdater.logger = log
  log.transports.file.level = 'info'

  autoUpdater.autoDownload = false

  autoUpdater.on('update-available', () => {
    win.webContents.send('update-available')
  })

  autoUpdater.on('update-downloaded', () => {
    win.webContents.send('update-downloaded')
  })

  ipcMain.on('check-for-updates', () => {
    autoUpdater.checkForUpdates()
  })

  ipcMain.on('download-update', () => {
    autoUpdater.downloadUpdate()
  })

  ipcMain.on('install-update', () => {
    autoUpdater.quitAndInstall()
  })
}

⚡ 方案二:增量更新(使用 .blockmap)

📦 构建配置(package.json)

json 复制代码
"build": {
  "appId": "com.example.myapp",
  "productName": "MyApp",
  "win": {
    "target": "nsis"
  },
  "nsis": {
    "differentialPackage": true
  },
  "publish": {
    "provider": "github",
    "owner": "your-github",
    "repo": "your-repo"
  }
}

🛠 发布文件(上传到 GitHub Releases)

  • MyApp Setup 1.0.1.exe
  • MyApp Setup 1.0.1.exe.blockmap
  • latest.yml

✅ 必须上传 .blockmap 才能启用增量下载。

📌 自动启用增量的前提:

  1. 上个版本的 .exe 文件完整可读取
  2. blockmap 文件无误
  3. 下载流程未被中断

🖥️ 通用渲染进程代码(App.vue)

vue 复制代码
<template>
  <div>
    <button @click="check">检查更新</button>
    <button v-if="canDownload" @click="download">下载更新</button>
    <button v-if="canInstall" @click="install">立即安装并重启</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
const canDownload = ref(false)
const canInstall = ref(false)

function check() {
  window.electronAPI.checkForUpdates()
}
function download() {
  window.electronAPI.downloadUpdate()
}
function install() {
  window.electronAPI.installUpdate()
}

onMounted(() => {
  window.electronAPI.onUpdateAvailable(() => (canDownload.value = true))
  window.electronAPI.onUpdateDownloaded(() => (canInstall.value = true))
})
</script>

🛡️ 通用 Preload 脚本(preload/index.ts)

ts 复制代码
import { contextBridge, ipcRenderer } from 'electron'

contextBridge.exposeInMainWorld('electronAPI', {
  checkForUpdates: () => ipcRenderer.send('check-for-updates'),
  downloadUpdate: () => ipcRenderer.send('download-update'),
  installUpdate: () => ipcRenderer.send('install-update'),
  onUpdateAvailable: (cb: () => void) => ipcRenderer.on('update-available', cb),
  onUpdateDownloaded: (cb: () => void) => ipcRenderer.on('update-downloaded', cb)
})

📊 方案比较总结

对比维度 全量更新 增量更新(blockmap)
下载内容 整包 .exe 差异块(基于 blockmap)
更新包大小 大(几十~百 MB) 小(几 MB)
下载速度 较慢 更快
网络负载
容错性 中等(依赖历史版本)
发布要求 .exe + .yml .exe + .blockmap + .yml
适用场景 初次发布、大改动 小版本热更、频繁更新

✅ 推荐使用建议

使用场景 推荐方案
第一次发布 ✅ 全量
结构或模块变动大 ✅ 全量
频繁发布小优化 ✅ 增量
低带宽用户环境 ✅ 增量
无法保证用户版本稳定 ✅ 全量

📚 延伸阅读

相关推荐
芭拉拉小魔仙10 小时前
【Vue3+TypeScript】H5项目实现企业微信OAuth2.0授权登录完整指南
javascript·typescript·企业微信
吃饭睡觉打豆豆嘛12 小时前
深入剖析 Promise 实现:从原理到手写完整实现
前端·javascript
Spider_Man12 小时前
从 “不会迭代” 到 “面试加分”:JS 迭代器现场教学
前端·javascript·面试
小高00712 小时前
🧙‍♂️ 老司机私藏清单:从“记事本”到“旗舰 IDE”,我只装了这 12 个插件
前端·javascript·vue.js
EveryPossible12 小时前
终止异步操作
前端·javascript·vue.js
Stringzhua13 小时前
setup函数相关【3】
前端·javascript·vue.js
neon120413 小时前
解决Vue Canvas组件在高DPR屏幕上的绘制偏移和区域缩放问题
前端·javascript·vue.js·canva可画
Sammyyyyy13 小时前
Node.js 做 Web 后端优势为什么这么大?
开发语言·前端·javascript·后端·node.js·servbay
Bling_Bling_114 小时前
面试常考:js中 Map和 Object 的区别
开发语言·前端·javascript
前端小巷子14 小时前
JS实现丝滑文字滚动
前端·javascript·面试