原生js結合electron。通過electron-builder和electron-updater打包並自動更新


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM