前言
之前寫過一篇關(guān)于 Windows 下通過 Electron 自帶的 autoUpdater 實現(xiàn)應(yīng)用自動更新的文章诬滩,很多小伙伴私信問我要具體實現(xiàn)代碼,不過因為之前一直很忙(還有懶...)。
這兩周正好周末比較空,除了在 github 上搭建了一個腳手架,還順便把實現(xiàn)優(yōu)化了一波球凰,下面將會帶著大家從零開始詳細(xì)介紹實現(xiàn)過程狮腿,對小白也很友好的教程哦腿宰。
從零開始
進(jìn)入你的工作目錄,比如 d/workspace
# 目錄 d/workspace
mkdir electron-demo # 新建文件夾 electron-demo
cd electron-demo # 進(jìn)入文件夾 electron-demo
npm init # 初始化 npm缘厢,一路回車即可
npm i electron --save-dev # 安裝 electron 依賴
touch main.js # 新建文件 main.js
touch index.html # 新建文件 index.html
現(xiàn)在你的文件結(jié)構(gòu)如下:
|- electron-demo
|- main.js # 空文件
|- index.html # 空文件
|- package.json
|- package-lock.json # npm 自動生成的文件
|- node_modules
確保 package.json 的name吃度,version,description這三個字段都不為空贴硫,main 字段的取值為 main.js 椿每。
{
"name": "electron-demo",
"version": "0.0.1",
"description": "electron-demo",
"main": "main.js"
}
主進(jìn)程和渲染進(jìn)程
Electron 應(yīng)用分為主進(jìn)程和渲染進(jìn)程。渲染進(jìn)程是直接與用戶產(chǎn)生交互的進(jìn)程英遭,也就是我們看到的一個個窗口頁面间护,而主進(jìn)程主要負(fù)責(zé)控制應(yīng)用的生命周期,負(fù)責(zé)各個渲染進(jìn)程的通信等挖诸。
我們的主進(jìn)程代碼寫在 main.js 中汁尺,所以首先在你心愛的代碼編輯中打開 main.js,輸入如下代碼:
const path = require('path');
const url = require('url');
const {
app,
BrowserWindow
} = require('electron');
app.on('ready', () => {
let win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
devTools: true
}
});
win.loadURL(
url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
})
);
});
app.on('window-all-closed', () => app.quit());
再打開 index.html多律,輸入如下代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
之后執(zhí)行
# 目錄 d/workspace/electron-demo
node_modules/.bin/electron .
不出意外的話你會看到一個彈出框痴突,像這樣:
我們也可以把 node_modules/.bin/electron .
保存成 npm 腳本搂蜓,方便以后調(diào)用。打開 package.json辽装,添加如下內(nèi)容:
"scripts": {
"start": "electron ."
}
以后只需要調(diào)用 npm start
即可帮碰。
到這里,我們已經(jīng)有了一個最簡單的 Electron 應(yīng)用拾积,如果你對繼續(xù)開發(fā)應(yīng)用本身更感興趣的話殉挽,請移步 Electron 官方文檔,因為接下來我們會專注在怎么讓這個應(yīng)用實現(xiàn)自動更新殷勘。
自動更新
安裝依賴
自動更新功能的實現(xiàn)依賴 electron-builder 和 electron-updater此再,所以我們需要先安裝這兩個依賴。
# 目錄 d/workspace/electron-demo
npm i electron-builder --save-dev # 必須安裝為開發(fā)依賴玲销,否則打包會出錯
npm i electron-updater --save # 必須安裝為運(yùn)行依賴输拇,否則運(yùn)行會出錯
配置 package.json
為了配合打包 package.json 需要新增字段 build:
"build": {
"appId": "com.xxx.app",
"publish": [
{
"provider": "generic",
"url": "http://127.0.0.1:8080"
}
]
},
同樣為了執(zhí)行方便,我們需要添加一個 npm 腳本贤斜,打開 package.json策吠,添加如下內(nèi)容:
"scripts": {
"start": "electron .",
"build": "electron-builder -w"
}
以后只需要調(diào)用 npm run build
即可。
主進(jìn)程和渲染進(jìn)程
打開main.js瘩绒,編輯后內(nèi)容如下:
const path = require('path');
const url = require('url');
const {
app,
BrowserWindow,
ipcMain
} = require('electron');
const { autoUpdater } = require('electron-updater');
const feedUrl = `http://127.0.0.1:8080/${process.platform}`;
let webContents;
let createWindow = () => {
let win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
devTools: true
}
});
webContents = win.webContents;
win.loadURL(
url.format({
pathname: path.join(__dirname, 'src/index.html'),
protocol: 'file:',
slashes: true
})
);
webContents.openDevTools();
};
let sendUpdateMessage = (message, data) => {
webContents.send('message', { message, data });
};
let checkForUpdates = () => {
autoUpdater.setFeedURL(feedUrl);
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) {
ipcMain.on('updateNow', (e, arg) => {
//some code here to handle event
autoUpdater.quitAndInstall();
})
sendUpdateMessage('isUpdateNow');
});
//執(zhí)行自動更新檢查
autoUpdater.checkForUpdates();
};
app.on('ready', () => {
createWindow();
setTimeout(checkForUpdates, 1000);
});
app.on('window-all-closed', () => app.quit());
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<script>
const { ipcRenderer } = require('electron');
ipcRenderer.on('message', (event, { message, data }) => {
console.log(message, data);
switch (message) {
case 'isUpdateNow':
if (confirm('現(xiàn)在更新猴抹?')) {
ipcRenderer.send('updateNow');
}
break;
default:
document.querySelector('h1').innerHTML = message;
break;
}
});
</script>
</body>
</html>
打包
npm run build
第一次運(yùn)行會比較慢,運(yùn)行結(jié)束后會在當(dāng)前目錄下新增一個 dist 文件夾锁荔,dist 的目錄結(jié)構(gòu)如下:
|- dist
|- win-unpacked
|- electron-autoupdate-scaffold Setup.exe
|- electron-autoupdate-scaffold Setup.exe.blockmap
|- electron-builder-effective-config.yaml
|- latest.yml
win-unpacked 下是可執(zhí)行文件蟀给,但是先別著急運(yùn)行,我們還缺一個后臺阳堕。
自動更新后臺
聰明的你一定注意到跋理,前面代碼中我們有一個:
const feedUrl = `http://127.0.0.1:8080/${process.platform}`;
所以我們現(xiàn)在要做的就是一個可以接受這個請求的服務(wù)。
回到你的工作目錄(d/workspace
)
# 目錄 d/workspace
mkdir electron-server
cd electron-server
npm init
npm i koa --save
npm i koa-static --save
touch server.js
打開 server.js恬总,輸入如下內(nèi)容:
// server.js
let Koa = require('koa');
let app = new Koa();
let path = require('path');
app.use(require('koa-static')(path.resolve(__dirname + '/packages')));
let server = app.listen(8080, () => {
let { address, port } = server.address();
console.log("應(yīng)用實例前普,訪問地址為 http://%s:%s", address, port);
});
將之前打包出來的 dist 目錄下的 4 個文件(除了 win-unpacked)拷貝到這邊的 packages/win32 下(新建目錄 packages/win32),之后
# 目錄 d/workspace/electron-server
npm start
到此為止壹堰,我們的自動更新服務(wù)就搭建完成了拭卿,現(xiàn)在來一波測試吧。
測試
-
進(jìn)入 electron-demo/dist/win-unpacked 找到可執(zhí)行文件贱纠,雙擊運(yùn)行峻厚,看到打開窗口的控制臺中依次輸出:
checking-for-update update-not-available
進(jìn)入 electron-demo,打開 package.json谆焊,把版本號改為0.0.2惠桃,重新打包后拷貝打包文件到自動更新后臺目錄(
d/workspace/electron-server/packages/win32
)。-
進(jìn)入 electron-demo,打開 package.json刽射,把版本號改為0.0.1军拟,重新打包后再次進(jìn)入 dist/win-unpacked 目錄,運(yùn)行 exe誓禁,看到打開窗口的控制臺中依次輸出:
checking-for-update update-available
并且出現(xiàn)彈窗提示「現(xiàn)在更新懈息?」。