开发人员联系方式:251746034@qq.com
代码库:https://github.com/chenjia/vue-desktop
示例:http://47.100.119.102/vue-desktop
目的:使用electron打包web桌面应用。
准备环境:nodejs
npm安装:
npm install --save-dev electron
npm install --save-dev electron-builder
npm install --save electron-updater
一、从github下载一个Electron应用
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start
package.json里面配置
<template>
"build": {
"electronVersion": "5.0.0",
"win": {
"requestedExecutionLevel": "highestAvailable",
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
]
},
"appId": "electron-desktop",
"artifactName": "electron-desktop-${version}-${arch}.${ext}",
"nsis": {
"artifactName": "electron-desktop-${version}-${arch}.${ext}"
},
"publish": [
{
"provider": "generic",
"url": "http://localhost:8080"
}
]
}
二、修改main.js
顶部引入
const {app, globalShortcut, ipcMain, BrowserWindow} = require('electron')
const {autoUpdater} = require('electron-updater')
底部添加
!function updateHandle() {
let message = {
error: '检查更新出错',
checking: '正在检查更新……',
updateAva: '检测到新版本,正在下载',
updateNotAva: '现在使用的就是最新版本,不用更新',
};
const uploadUrl = "http://localhost:8080";
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = false
autoUpdater.setFeedURL(uploadUrl);
autoUpdater.on('error', function (error) {
const messageObj = {status:'error', message: message.error, error: error}
sendUpdateMessage(JSON.stringify(messageObj))
});
autoUpdater.on('checking-for-update', function () {
const messageObj = {status:'checking', message: message.checking}
sendUpdateMessage(JSON.stringify(messageObj))
});
autoUpdater.on('update-available', function (info) {
const messageObj = {status:'updateAva', message: message.updateAva, currentVersion: autoUpdater.currentVersion, info: info}
sendUpdateMessage(JSON.stringify(messageObj))
});
autoUpdater.on('update-not-available', function (info) {
const messageObj = {status:'updateNotAva', message: message.updateNotAva, info: info}
sendUpdateMessage(JSON.stringify(messageObj))
});
autoUpdater.on('download-progress', function (progressObj) {
mainWindow.webContents.send('downloadProgress', progressObj)
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
autoUpdater.quitAndInstall()
})
ipcMain.on("checkForUpdate",()=>{
console.log('checkForUpdate')
autoUpdater.checkForUpdates()
})
ipcMain.on('downloadUpdate', (e, arg) => {
autoUpdater.downloadUpdate()
})
}();
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
三、修改你控制更新逻辑的js
本文以vue为例,先编写一个更新的组件,Dialog为你的弹窗组件,ProgressBar为进度条组件,UI组件需根据你自己的项目而定
<template>
<Dialog
:title="'正在更新版本('+version+')'"
ref="updateDialog"
:dialogStyle="{width:'480px',height:(172+30*updateMessage.length)+'px'}"
:modal="true"
:closable="false"
:draggable="false"
:resizable="false">
<ul style="list-style: none;padding-inline-start:20px;line-height:30px;">
<li style="font-size:16px;">更新内容:<span v-if="!updateMessage || updateMessage.length == 0">这个人很懒,没有版本描述</span></li>
<li v-for="(item, index) in updateMessage" :key="index">{{item}}</li>
</ul>
<div class="center" style="padding:0 20px 10px;">
<p v-if="downloadPercent<100">下载进度:{{downloadPercent}}%</p>
<p v-else>下载已完成正在安装,稍后会自动重新打开</p>
<ProgressBar :value="downloadPercent"></ProgressBar>
</div>
</Dialog>
</template>
<script>
export default {
name: "update",
props: {
downloadPercent:{
type: Number,
required: true,
default: 0
},
version:{
type: String,
required: true
},
updateMessage:{
type: Array
}
}
}
</script>
在App.vue的template中添加更新组件
组件挂载完成后加入更新代码
<template>
<Update v-if="updating" :downloadPercent="downloadPercent" :version="version" :updateMessage="updateMessage"></Update>
</template>
//别忘了引入组件
import Update from './Update'
mounted(){
const _this = this
if (window.require) {
let ipc = window.require('electron').ipcRenderer
ipc.send("checkForUpdate")
ipc.on("message", (event, text) => {
const message = JSON.parse(text)
if(message.status == 'updateAva'){
this.$messager.confirm({
title: '版本更新( '+message.currentVersion.version+' -> '+message.info.version+' )',
msg: '发现新版本,确认要更新到新版本吗?',
result(r){
if(r) {
_this.updating = true
_this.version = message.info.version
if(message.info.updateMessage){
_this.updateMessage = message.info.updateMessage
}
ipc.send("downloadUpdate")
}
}
})
}
console.log(event,text)
})
ipc.on("downloadProgress", (event, progressObj)=> {
this.downloadPercent = parseInt(progressObj.percent || 0);
console.log(this.downloadPercent)
if(this.downloadPercent > 100){
this.downloadPercent = 100
this.updating = false
}
})
}
}
四、打包成window或mac相应的客户端
执行 electron-builder --win --x64
注意:mac环境下打包执行electron-builder,因为ios应用程序需要证书,所以没有证书的情况下是只能打包程序运行,但不能使用在线更新功能。
之后会在dist文件夹里面生成exe文件,mac环境会生成dmg文件,安装该文件后打开应用会检查更新地址是否有新版本可更新
main.js const uploadUrl = “http://localhost:8080”;
package.json “url”: “http://localhost:8080”
这两个具体用的哪个没有测试,都改掉肯定没错。
打包后会在dist目录生成一个latest.yml文件,里面保存的是版本信息,可以在最后加入版本描述字段 updateMessage(这是自定义字段,可随意添加),这个字段在你的js里面可以获取到并提示给用户查看更新内容。
version: 1.0.1
files:
- url: electron-desktop-1.0.1.exe
sha512: v1dD2XzcpCemURrTWrCHxkkRjGqZJS8UjAKBgvuXnPblgnpkbDnELTWuDHM6b46r/O2ObM0EO3QOpZI5S6Z10Q==
size: 63465462
path: electron-desktop-1.0.1.exe
sha512: v1dD2XzcpCemURrTWrCHxkkRjGqZJS8UjAKBgvuXnPblgnpkbDnELTWuDHM6b46r/O2ObM0EO3QOpZI5S6Z10Q==
releaseDate: '2019-05-21T01:40:57.107Z'
updateMessage:
- 1. 优化首屏加载速度
- 2. 修复少量的bug
- 3. 测试增量更新功能
由于安装文件特别大,一般有60M+,建议在本地npm install -g http-server,然后在更新文件的目录执行http-server,启动静态web服务测试更新。
好了,最后附上效果图: