如何使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新
說(shuō)明:
本文的自動(dòng)更新功能使用的項(xiàng)目為 electron-vue 腳手架搭建一個(gè)默認(rèn)項(xiàng)目。
參考的文章如下:
- electron-vue 中文文檔
- electron-builder 文檔
- Windows 下支持自動(dòng)更新的 Electron 應(yīng)用腳手架
- Electron 文檔 Docs / API / autoUpdater
開(kāi)始:新建一個(gè) electron 項(xiàng)目
首先你得有一個(gè)需要配置自動(dòng)更新功能的 electron 項(xiàng)目。這里我為了測(cè)試自動(dòng)更新功能是否成功搭建使用的是 electron-vue 腳手架搭建的項(xiàng)目。
搭建過(guò)程如下:
# 安裝 vue-cli 和 腳手架樣板代碼 npm install -g vue-cli vue init simulatedgreg/electron-vue autoUpdataTest # 安裝依賴(lài)并運(yùn)行你的程序 cd autoUpdataTest npm install npm run dev
程序運(yùn)行后的界面如下:
腳手架生成的文件結(jié)構(gòu):
|- autoUpdateTest |- .electron-vue # 壓縮及運(yùn)行環(huán)境的配置文件 |- build # |- icons # 圖標(biāo)文件 |- ... # 打包生成的文件在此處 |- dist # 用 webpack 壓縮項(xiàng)目后生成的壓縮文件在此處 |- node_modules |- src # 資源文件 |- main # 主進(jìn)程 |- renderer # 渲染進(jìn)程 |- index.ejx # 入口文件 |- static # 靜態(tài)資源 |- .babelrc |- .gitignore |- .travis |- appveyor.yml |- package-lock.json # npm 自動(dòng)生成的文件 |- package.json |- README.md
使用 electron-builder 最關(guān)鍵的配置在 package.json 里:(為了觀(guān)察我們所需要的地方,把此篇文章里不需要關(guān)注的代碼給刪掉了。)
{ "name": "autoupdatetest", "version": "0.0.0", "author": "wonder <xxxxxxxxx@qq.com>", "description": "An electron-vue project", "main": "./dist/electron/main.js", "scripts": { "build": "node .electron-vue/build.js && electron-builder", "dev": "node .electron-vue/dev-runner.js", }, "build": { "productName": "autoupdateteset", "appId": "org.simulatedgreg.electron-vue", "directories": { "output": "build" }, "files": "dist/electron/**/*", "win": { "icon": "build/icons/icon.ico" } }, "dependencies": { }, "devDependencies": { } }
解析:
前四行是一般的 package.json 會(huì)有的:
name
— 項(xiàng)目名version
— 版本號(hào)author
— 開(kāi)發(fā)人員及郵箱號(hào)description
— 項(xiàng)目描述 。
下面重點(diǎn)看后面的內(nèi)容:electron-builder詳細(xì)配置文檔
- "main": "./dist/electron/main.js" — 這里的 main 入口文件指的是用 electron-builder 打包主程序的入口文件,這里的路徑是使用 webpack 壓縮項(xiàng)目后文件輸出的位置。
- scripts — 腳本
- "build": "node .electron-vue/build.js && electron-builder" — 生產(chǎn)環(huán)境,壓縮打包項(xiàng)目。先運(yùn)行 .electron-vue 文件夾下的 build.js 腳本對(duì)項(xiàng)目進(jìn)行壓縮,輸出的位置在 dist 文件夾下,然后再使用配置好的 electron-builder 對(duì) dist 文件夾下的文件進(jìn)行打包生成應(yīng)用的安裝包。
- "dev": "node .electron-vue/dev-runner.js" — 開(kāi)發(fā)環(huán)境,可以運(yùn)行我們的項(xiàng)目并測(cè)試。這里使用了熱更新,改動(dòng)代碼不需要刷新即可看到應(yīng)用的改變。
- build — electron-builder 配置項(xiàng)
- "productName": "autoupdateteset", — 工程項(xiàng)目名
- "appId": "org.simulatedgreg.electron-vue" — 應(yīng)用程序 ID。強(qiáng)烈建議設(shè)置顯式ID。
- directories
- "output": "build" — 生成的安裝包輸出目錄。
- "files": "dist/electron/**/*" — 安裝包源文件目錄,支持多路徑(數(shù)組)
- "win": { "icon": "build/icons/icon.ico"} — 打包成 Windows 系統(tǒng)下安裝包應(yīng)用程序圖標(biāo)路徑,還有別的配置項(xiàng)可以在詳細(xì)文檔中查看。
有關(guān) electron-vue 的使用的更詳細(xì)的說(shuō)明請(qǐng)看 中文文檔。
自動(dòng)更新
安裝依賴(lài)
自動(dòng)更新功能的實(shí)現(xiàn)依賴(lài) electron-builder
和 electron-updater
。
因?yàn)槲覀兪怯玫膃lectron-builder腳手架生成的項(xiàng)目,已經(jīng)有 electron-builder
依賴(lài)了,所以只需要安裝 electron-updater
。
# 目錄 E:\GitHub\autoupdateteset npm i electron-updater --save # 必須安裝為運(yùn)行依賴(lài),否則運(yùn)行會(huì)出錯(cuò)
配置 package.json
為了配合打包 package.json 需要給 build 新增配置項(xiàng):
"build": { "publish": [ { "provider": "generic", "url": "http://127.0.0.1:5500/" #這里是我本地開(kāi)的服務(wù)器的地址 } ], ... }
主進(jìn)程(參考:electron 中文文檔)
主進(jìn)程的入口文件是 src/main/index.js
。
import { app, // app 模塊是為了控制整個(gè)應(yīng)用的生命周期設(shè)計(jì)的。 BrowserWindow, // BrowserWindow 類(lèi)讓你有創(chuàng)建一個(gè)瀏覽器窗口的權(quán)力。 ipcMain } from 'electron'; // 引入自動(dòng)更新模塊 const { autoUpdater } = require('electron-updater'); // 不支持 ES6 則用如下方式引入 // const autoUpdater = require("electron-updater").autoUpdater const feedUrl = `http://127.0.0.1:5500/win32`; // 更新包位置 /** * Set `__static` path to static files in production * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html */ if (process.env.NODE_ENV !== 'development') { global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\'); } let mainWindow, webContents; const winURL = process.env.NODE_ENV === 'development' ? `http://localhost:9080` : `file://${__dirname}/index.html`; function createWindow() { /** * Initial window options */ mainWindow = new BrowserWindow({ height: 563, useContentSize: true, width: 1000 }); mainWindow.loadURL(winURL); webContents = mainWindow.webContents; mainWindow.on('closed', () => { mainWindow = null; }); } // 主進(jìn)程監(jiān)聽(tīng)渲染進(jìn)程傳來(lái)的信息 ipcMain.on('update', (e, arg) => { console.log("update"); checkForUpdates(); }); let checkForUpdates = () => { // 配置安裝包遠(yuǎn)端服務(wù)器 autoUpdater.setFeedURL(feedUrl); // 下面是自動(dòng)更新的整個(gè)生命周期所發(fā)生的事件 autoUpdater.on('error', function(message) { sendUpdateMessage('error', message); }); autoUpdater.on('checking-for-update', function(message) { sendUpdateMessage('checking-for-update', message); }); autoUpdater.on('update-available', function(message) { sendUpdateMessage('update-available', message); }); autoUpdater.on('update-not-available', function(message) { sendUpdateMessage('update-not-available', message); }); // 更新下載進(jìn)度事件 autoUpdater.on('download-progress', function(progressObj) { sendUpdateMessage('downloadProgress', progressObj); }); // 更新下載完成事件 autoUpdater.on('update-downloaded', function(event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) { sendUpdateMessage('isUpdateNow'); ipcMain.on('updateNow', (e, arg) => { autoUpdater.quitAndInstall(); }); }); //執(zhí)行自動(dòng)更新檢查 autoUpdater.checkForUpdates(); }; // 主進(jìn)程主動(dòng)發(fā)送消息給渲染進(jìn)程函數(shù) function sendUpdateMessage(message, data) { console.log({ message, data }); webContents.send('message', { message, data }); } app.on('ready', () => { createWindow(); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (mainWindow === null) { createWindow(); } });
渲染進(jìn)程
渲染進(jìn)程的入口文件是 src/renderer/index.js
。
這里我們主要修改 App.vue
,將原來(lái)的內(nèi)容全刪掉并使更新的整個(gè)周期在界面上打印出來(lái)。
<template> <div id="app"> <!-- <router-view></router-view> --> <button @click="autoUpdate()">獲取更新</button> <ol id="content"> <li>生命周期過(guò)程展示</li> </ol> </div> </template> <script> // import { ipcRenderer } from 'electron'; const { ipcRenderer } = require('electron'); export default { name: 'my-project1', mounted() { var _ol = document.getElementById("content"); ipcRenderer.on('message',(event,{message,data}) => { let _li = document.createElement("li"); _li.innerHTML = message + " <br>data:" + JSON.stringify(data) +"<hr>"; _ol.appendChild(_li); if (message === 'isUpdateNow') { if (confirm('是否現(xiàn)在更新?')) { ipcRenderer.send('updateNow'); } } }); }, methods: { autoUpdate() { ipcRenderer.send('update'); } } }; </script> <style> /* CSS */ </style>
顯示的界面如下:
自動(dòng)更新過(guò)程簡(jiǎn)單介紹
1.將 webpack.json 里的版本號(hào)先改為 0.0.1,然后npm run build
生成一個(gè)版本為0.0.1的安裝包。
注意上面一步會(huì)生成一個(gè)latest.yml
文件,autoUpdate 實(shí)際上通過(guò)檢查該文件中安裝包版本號(hào)與當(dāng)前應(yīng)用版本號(hào)對(duì)比來(lái)進(jìn)行更新判斷的。
latest.yml
文件內(nèi)容如下:
2.然后將上一步生成的安裝包放在本地開(kāi)啟的服務(wù)器文件夾下,對(duì)應(yīng)你在主程序入口文件中配置的服務(wù)器位置。
3.將 package.json 中的版本號(hào)改回0.0.0,再npm run build
一遍,運(yùn)行 build 文件夾下的 exe 安裝包,就將軟件安裝在你電腦里面了。點(diǎn)擊安裝完成后桌面上的快捷方式,再次點(diǎn)擊上面的獲取更新的按鈕就可以看到顯示在界面的自動(dòng)更新生命周期了。(但這里因?yàn)闀?huì)給你直接自動(dòng)更新,所以會(huì)一閃而過(guò),你可以在 autoUpdate 的各個(gè)生命周期事件里設(shè)置主進(jìn)程與渲染進(jìn)程通信,則可以一步一步觀(guān)察到整個(gè)自動(dòng)更新的生命周期了。)
通過(guò)測(cè)試總結(jié) autoUpdate 生命周期圖
更新過(guò)程展示
1、無(wú)版本更新
2、有版本更新
點(diǎn)擊取消后會(huì)先不更新,在應(yīng)用關(guān)閉后更新:
點(diǎn)擊確認(rèn)后則會(huì)直接更新:
踩過(guò)的坑
1、主進(jìn)程與渲染進(jìn)程通信
最開(kāi)始我是直接在主進(jìn)程直接運(yùn)行更新
然后想在渲染進(jìn)程中打印主進(jìn)程傳過(guò)來(lái)的消息,但是發(fā)現(xiàn)只有 isUpdateNow 事件運(yùn)行時(shí)才有日志顯示。
結(jié)果發(fā)現(xiàn)原來(lái)主進(jìn)程與渲染進(jìn)程之間通信必須在渲染進(jìn)程已經(jīng)運(yùn)行的時(shí)候(即那個(gè)界面完全顯示出來(lái))才能夠進(jìn)行。所以我將自動(dòng)更新改為界面按鈕觸發(fā),這樣才能檢測(cè)到自動(dòng)更新的整個(gè)流程。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vue配置electron使用electron-builder進(jìn)行打包的操作方法
- electron-vite工具打包后如何通過(guò)內(nèi)置配置文件動(dòng)態(tài)修改接口地址
- electron實(shí)現(xiàn)讀取和寫(xiě)入配置文件的示例詳解
- vue中electron框架自定義外部配置文件的配置與讀取辦法
- vite?+?electron-builder?打包配置詳解
- electron-builder打包配置詳解
- vue3+electron12+dll開(kāi)發(fā)客戶(hù)端配置詳解
- Electron 使用 Nodemon 配置自動(dòng)重啟的方法
相關(guān)文章
JavaScript實(shí)現(xiàn)小程序圖片裁剪功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)小程序圖片裁剪功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-03-03fw.qq.com/ipaddress已失效 javascript獲得客戶(hù)端IP的新方法
一直以來(lái),我都是通過(guò)http://fw.qq.com/ipaddress來(lái)獲得客戶(hù)端用戶(hù)的IP,這個(gè)方法簡(jiǎn)單、快速、實(shí)用2012-01-01JavaScript獲取XML數(shù)據(jù)附示例截圖
這篇文章主要介紹了JavaScript獲取XML數(shù)據(jù)的方法,需要的朋友可以參考下2014-03-03javascript中BOM基礎(chǔ)知識(shí)總結(jié)
本文主要對(duì)javascript中BOM基礎(chǔ)知識(shí)進(jìn)行總結(jié)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02promise處理多個(gè)相互依賴(lài)的異步請(qǐng)求(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇promise處理多個(gè)相互依賴(lài)的異步請(qǐng)求(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08TypeScript判斷兩個(gè)數(shù)組的內(nèi)容是否相等的實(shí)現(xiàn)
本文主要介紹了TypeScript?判斷兩個(gè)數(shù)組的內(nèi)容是否相等,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11