溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

發(fā)布時(shí)間:2021-02-07 10:56:31 來源:億速云 閱讀:1274 作者:小新 欄目:web開發(fā)

這篇文章給大家分享的是有關(guān)怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

自動(dòng)更新功能使用的項(xiàng)目為 electron-vue 腳手架搭建一個(gè)默認(rèn)項(xiàng)目。

開始:新建一個(gè) electron 項(xiàng)目

首先你得有一個(gè)需要配置自動(dòng)更新功能的 electron 項(xiàng)目。這里我為了測試自動(dòng)更新功能是否成功搭建使用的是 electron-vue 腳手架搭建的項(xiàng)目。

搭建過程如下:

# 安裝 vue-cli 和 腳手架樣板代碼
npm install -g vue-cli
vue init simulatedgreg/electron-vue autoUpdataTest

# 安裝依賴并運(yùn)行你的程序
cd autoUpdataTest
npm install
npm run dev

程序運(yùn)行后的界面如下:

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

腳手架生成的文件結(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)注的代碼給刪掉了。)

{
 "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 — 版本號

  • author — 開發(fā)人員及郵箱號

  • 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 腳本對項(xiàng)目進(jìn)行壓縮,輸出的位置在 dist 文件夾下,然后再使用配置好的 electron-builder 對 dist 文件夾下的文件進(jìn)行打包生成應(yīng)用的安裝包。

    • "dev": "node .electron-vue/dev-runner.js" — 開發(fā)環(huán)境,可以運(yùn)行我們的項(xiàng)目并測試。這里使用了熱更新,改動(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ì)的說明請看 中文文檔。

自動(dòng)更新

安裝依賴

自動(dòng)更新功能的實(shí)現(xiàn)依賴 electron-builderelectron-updater。

因?yàn)槲覀兪怯玫膃lectron-builder腳手架生成的項(xiàng)目,已經(jīng)有 electron-builder 依賴了,所以只需要安裝 electron-updater

# 目錄 E:\GitHub\autoupdateteset
npm i electron-updater --save # 必須安裝為運(yùn)行依賴,否則運(yùn)行會(huì)出錯(cuò)

配置 package.json

為了配合打包 package.json 需要給 build 新增配置項(xiàng):

"build": {
 "publish": [
  {
   "provider": "generic",
   "url": "http://127.0.0.1:5500/" #這里是我本地開的服務(wù)器的地址
  }
 ],
 ...
}

主進(jìn)程(參考:electron 中文文檔)

主進(jìn)程的入口文件是 src/main/index.js。

import { 
app,   // app 模塊是為了控制整個(gè)應(yīng)用的生命周期設(shè)計(jì)的。
BrowserWindow, // BrowserWindow 類讓你有創(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)聽渲染進(jìn)程傳來的信息
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,將原來的內(nèi)容全刪掉并使更新的整個(gè)周期在界面上打印出來。

<template>
 <div id="app">
  <!-- <router-view></router-view> -->
  <button @click="autoUpdate()">獲取更新</button>
  <ol id="content">
   <li>生命周期過程展示</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>

顯示的界面如下:

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

自動(dòng)更新過程簡單介紹

1.將 webpack.json 里的版本號先改為 0.0.1,然后npm run build生成一個(gè)版本為0.0.1的安裝包。

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新 

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

注意上面一步會(huì)生成一個(gè)latest.yml文件,autoUpdate 實(shí)際上通過檢查該文件中安裝包版本號與當(dāng)前應(yīng)用版本號對比來進(jìn)行更新判斷的。

latest.yml文件內(nèi)容如下:

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

2.然后將上一步生成的安裝包放在本地開啟的服務(wù)器文件夾下,對應(yīng)你在主程序入口文件中配置的服務(wù)器位置。

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

3.將 package.json 中的版本號改回0.0.0,再npm run build一遍,運(yùn)行 build 文件夾下的 exe 安裝包,就將軟件安裝在你電腦里面了。點(diǎn)擊安裝完成后桌面上的快捷方式,再次點(diǎn)擊上面的獲取更新的按鈕就可以看到顯示在界面的自動(dòng)更新生命周期了。(但這里因?yàn)闀?huì)給你直接自動(dòng)更新,所以會(huì)一閃而過,你可以在 autoUpdate 的各個(gè)生命周期事件里設(shè)置主進(jìn)程與渲染進(jìn)程通信,則可以一步一步觀察到整個(gè)自動(dòng)更新的生命周期了。)

通過測試總結(jié) autoUpdate 生命周期圖

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

更新過程展示

1、無版本更新

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新 

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

2、有版本更新

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新 

點(diǎn)擊取消后會(huì)先不更新,在應(yīng)用關(guān)閉后更新:

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新 

點(diǎn)擊確認(rèn)后則會(huì)直接更新:

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新

踩過的坑

1、主進(jìn)程與渲染進(jìn)程通信

最開始我是直接在主進(jìn)程直接運(yùn)行更新

怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新 

然后想在渲染進(jìn)程中打印主進(jìn)程傳過來的消息,但是發(fā)現(xiàn)只有 isUpdateNow 事件運(yùn)行時(shí)才有日志顯示。

結(jié)果發(fā)現(xiàn)原來主進(jìn)程與渲染進(jìn)程之間通信必須在渲染進(jìn)程已經(jīng)運(yùn)行的時(shí)候(即那個(gè)界面完全顯示出來)才能夠進(jìn)行。所以我將自動(dòng)更新改為界面按鈕觸發(fā),這樣才能檢測到自動(dòng)更新的整個(gè)流程。

感謝各位的閱讀!關(guān)于“怎么使用electron-builder及electron-updater給項(xiàng)目配置自動(dòng)更新”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI