一.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{ width: 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了!
