一.package.json文件
先展示一个最终的package.json文件。后边再说都是怎么来的。(注释部分手动清理)
还有些
{ "name": "name",//项目名 "main": "main.js", "version": "0.0.2", "scripts": { "start": "electron .", "pack": "electron-builder --dir", "dist": "electron-builder" //打包命令 npm run dist 就可以执行打包 },
//默认安装完electron-builder会在dependencies里,一定要放在这。要不然会报模块找不到 "devDependencies": { "electron": "^10.1.1", "electron-builder": "^22.8.0", "menu": "^0.2.5", "path": "^0.12.7", "socket.io": "^2.3.0" },
//其他的electron就要放在这。要不然也会报模块找不到(最重要的就是electron-updater) "dependencies": { "is-electron": "^2.2.0", "electron-log": "^4.2.4", "electron-updater": "^4.3.4" }, "build": { "productName": "naem",//应用名称 "appId": "**",//应用程序id "directories": { "output": "build"//输出目录 },
//electron-updater需要的 "publish": [ { "provider": "generic", "url": "http://localhost/",//放latest.yml和.exe文件的服务器路径。(这里我用的nginx) "updaterCacheDirName": "name-updater" } ],
//安装包源文件目录 把一些公用的提出来,要不然有可能找不到。 "files": [ "./installer.nsh", "./icon.ico", "./index.html", "./main.js", "./package.json", "app/**/*" ],
//是否用asar打包,默认是true。如果用asar打包的话,那么项目目录将会都打包到asar中。打包完的resource中看不到项目目录
//如果不用他打包的话,那么resource中将会有完整的项目路径
//当然就算用asar打包的话。也可以下载asar模块,进行解压。 一般为true默认就好
"asar":false,
"dmg": { "contents": [ { "x": 410, "y": 150, "type": "link", "path": "/Applications" }, { "x": 130, "y": 150, "type": "file" } ] }, "mac": { "icon": "./icon.png", "artifactName": "${productName}_setup_${version}.${ext}" }, "win": { "icon": "./icon.png",//exe图标 "artifactName": "${productName}_setup_${version}.${ext}" //exe名称 }, "linux": { "icon": "./icon.png", "artifactName": "${productName}_setup_${version}.${ext}" },
//增加用户体验的配置(说白了就是安装界面的配置)更人性化了一点 "nsis": { "oneClick": false,//一键安装 "allowElevation": true,//如果为false,就必须提升权限重新启动安装 "allowToChangeInstallationDirectory": true,//修改安装目录 "installerIcon": "./tianyiyun.ico",//安装图标 "uninstallerIcon": "./tianyiyun.ico",//卸载图标 "createDesktopShortcut": true,//快捷方式 "createStartMenuShortcut": true,////开始菜单图标 "include": "./installer.nsh" //自定义脚本。比如一些开机启动啊一类的。可以自己写、找。找不到就算了吧。
"script" : "build/script/installer.nsh" // NSIS脚本的路径,用于自定义安装程序。 默认为build / installer.nsi
//最后两个一般不要,除非你想花里胡哨! } },
//文件输出。可以把文件输出到其他目录。(这里我的是找不到exe图标。所以输出了下) "extraResources": { "from": "/icon.png", "to": "./" } }
1.1 安装依赖(electron-bulider和electron-updater)
推荐使用tyarn或者cnpm。(因为快)
cnpm install electron-builder --save
cnpm install electron-updater--save
安装完package.json中会出现这样的配置。上边也说过。一定要改到devDependencies里
安装updater时。千万别动。就放在dependencies里。如果还有其他的electron-... ,的模块。也都放在dependencies里
"dependencies": {
....
"electron-builder": "^22.8.0"
},
二.主进程配置
可以放在main.js里。也可以放在main文件夹下的index.js中(我是放在了main.js了)上代码!
1 const electron = require('electron'); 2 const app = electron.app; 3 const path = require('path'); 4 const log = require('electron-log') 5 log.transports.console.level = false 6 log.transports.console.level = 'silly' 7 // 注意这个autoUpdater不是electron中的autoUpdater 8 const { autoUpdater } = require("electron-updater"); 9 // 更新路径 10 let updateUrl=''; 11 app.on('ready', function () { 12 //自己的业务代码 13 . 14 . 15 . 16 17 // 判断是否是生产环境 18 if (!app.isPackaged) { 19 // 调试功能 20 mainWindow.openDevTools(); 21 updateUrl = "http://localhost/" 22 }else{ 23 // 更新服务器地址 24 mainWindow.openDevTools();
//放打包完exe文件和latest.yml文件的路径 25 updateUrl = "http://服务器地址/" 26 27 } 28 //调用检查更新 29 updateHandle() 30 } 31 32 33 // 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写 34 function updateHandle() { 35 let versionInfo = '' 36 let message = { 37 error: '检查更新出错', 38 checking: '正在检查更新……', 39 updateAva: '检测到新版本', 40 updateNotAva: '现在使用的就是最新版本,不用更新', 41 }; 42 // 设置是否自动下载,默认是true,当点击检测到新版本时,会自动下载安装包,所以设置为false 43 autoUpdater.autoDownload = false 44 autoUpdater.logger = log 45 const os = require('os'); 46 47 autoUpdater.setFeedURL(updateUrl); 48 autoUpdater.on('error', function (error) { 49 sendUpdateMessage(message.error) 50 }); 51 autoUpdater.on('checking-for-update', function () { 52 sendUpdateMessage(message.checking) 53 }); 54 autoUpdater.on('update-available', function (info) { 55 sendUpdateMessage(message.updateAva) 56 // 是否下载 57 mainWindow.webContents.send('isDownloadUpdate', versionInfo); 58 }); 59 autoUpdater.on('update-not-available', function (info) { 60 sendUpdateMessage(message.updateNotAva) 61 }); 62 63 // 更新下载进度事件 64 autoUpdater.on('download-progress', function (progressObj) { 65 // log.info(winURL) 66 // log.warn(progressObj) 67 mainWindow.webContents.send('downloadProgress', progressObj) 68 }); 69 70 // 更新下载完成事件 71 autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) { 72 73 ipcMain.on('updateNow', (e, arg) =>{ 74 console.log(arguments); 75 console.log("开始更新"); 76 //some code here to handle event 77 autoUpdater.quitAndInstall(); 78 }); 79 80 mainWindow.webContents.send('isUpdateNow',versionInfo) 81 }); 82 83 ipcMain.on("checkForUpdate",()=>{ 84 //执行自动更新检查 85 let checkInfo = autoUpdater.checkForUpdates() 86 checkInfo.then(function (data) { 87 versionInfo = data.versionInfo // 获取更新包版本等信息 88 }) 89 }); 90 91 ipcMain.on('downloadUpdate', () => { 92 // 下载 93 log.warn('执行下载') 94 autoUpdater.downloadUpdate() 95 }) 96 } 97 98 // 通过main进程发送事件给renderer进程,提示更新信息 99 function sendUpdateMessage(text) { 100 mainWindow.webContents.send('message', text) 101 }
三.触发监听事件
触发监听事件一般都是在第一个页面来做的。我这里是登录页 login.js
现在登录页的created方法中触发。一启动程序。就会检查是否需要更新
created() { . . . // electron应用启动后主动触发检查更新函数 ipcRenderer.send("checkForUpdate"); },
然后检查到有新版本的时候,main.js里的方法就会调用这些监听事件,来处理升级版本
//下载过程 //downloadProgress事件可能因为下载速度太快,无法触发的问题 ipcRenderer.on("downloadProgress", (event, progressObj)=> { // 打开下载进度样式 app.$data.download=true; //progressObj.percent 下载进度 if( Math.trunc(progressObj.percent)){ let y = Math.trunc(progressObj.percent) var elem=document.getElementById("ch"); //获取ch if (y==100){ elem.style.backgroundColor="green";//百分百后背景颜色变化 console.log('下载完成!') } elem.style.width=y+'%'; elem.innerHTML=y+"%";// 计数值 } }); ipcRenderer.on('isUpdateNow', (event, versionInfo) => { // 自定义选择效果,效果自行编写 console.log(versionInfo) alert("版本"+versionInfo.version+"下载完成,立即退出升级") ipcRenderer.send('updateNow') }) ipcRenderer.on('isDownloadUpdate', (event, versionInfo) => { // 自定义选择效果,效果自行编写 console.log(versionInfo) if(confirm("检测到新版本,是否立即升级?")){ console.log('正在升级!') ipcRenderer.send('downloadUpdate') }else{ console.log('取消升级!') } })
下载进度的样式可以自己写的炫酷点,我这里比较简单。甚至有点难看【捂脸】
//html代码,我这里就放在login.html页面了 <div id="download" v-show='download' > <div id="ch"> </div> //css代码 #ch{ 0px; height: 50px; background-color: pink; text-align: right; color: green; line-height: 50px; box-sizing: content-box; }
现在所有的配置都已经完成了,就可以测试自动升级了
四.自动升级
先把package.json里的版本改成0.0.1,然后执行npm run dist(在package.json里配置的)打包。然后出现一个build的目录,里面有两个非常重要的东西
latest.yml和.exe文件,这两个是要放在服务器下的(package.json里的publish下的url)然后如果有新版本的话,程序就会自动检查到然后更新了
其他的文件就没啥了。第一个是exe的图标,第二个相当于执行.exe文件安装的安装目录。
五.总结
到了现在electron的打包并自动更新就简简单单的配置完成了,如果第一次弄这个,可能会有点懵,没关系,跟着步骤看着注解,一步一步的来就可以了,先看效果。
然后慢慢的就可以了,如果有啥不一样的、或者有问题,欢迎评论留言哦~ 咱们一起沟通解决写
ok了!