这里我将讲解一下从0搭建一个electron最简版架子,以及如何实现打包自动化更新
之前我有写过两篇文章关于electron框架概述以及 常用api的使用,感兴趣的同学可以看看
Electron桌面应用开发
Electron桌面应用开发2
搭建electron
官方文档:https://www.electronjs.org/zh/
只需要三个文件就可以跑起来electron
创建一个文件目录
mkdir my-electron-app && cd my-electron-app yarn init
然后,将 electron 包安装到应用的开发依赖中。
yarn add --dev electron
{ "name": "my-electron-app", "version": "1.0.0", "description": "Hello World!", "main": "main.js", // 入口文件 "author": "Jane Doe", "license": "MIT", "scripts": { "start": "electron ." }, "devDependencies": { "electron": "^27.0.3", } }
main.js
const createWindow = () => { const win = new BrowserWindow({ width: 800, height: 600 }) win.loadFile('index.html') // 加载index.html }
index.html
你好!你好!
我们正在使用 Node.js , Chromium , 和 Electron .
yarn start就可以启动起来,这是最简版的框架
配置打包、自动升级
这里强调一下
做mac的打包需要开通苹果开发者账号,购买证书,打包需要签名,这里购买和配置的流程很复杂就不做过多赘述,都搜的到。
其实windows也需要签名 证书,但是不提供也可以打包
打包和自动升级用到了官方提供的两个工具
打包:electron-builder
升级:electron-updater
electron-builder官方文档地址:https://www.electron.build/configuration/win#WindowsConfiguration-certificateSubjectName
如果觉得英文看着不方便,有大神中文总结了一下,地址:https://blog.csdn.net/qq_38830593/article/details/89843722
首先下载这两个库:
yarn add electron-builder -D
yarn add electron-updater
package.json里做参数配置
看build参数,各个参数对照着官方文档
{ "name": "electron-test", "version": "1.0.0", "description": "Hello World!", "main": "main.js", "license": "MIT", "scripts": { "start": "electron .", "build": "electron-builder" }, "build": { "productName": "electron-test", "appId": "cn.legaldawn.Lawdawn", "copyright": "版权所有信息", "asar": false, "directories": { "output": "dist" }, "dmg": { "artifactName": "${name}-${version}.${ext}" }, "publish": [ { "provider": "generic", "url": "https://lawdawn-download.oss-cn-beijing.aliyuncs.com/win-2023-11-04-1/" } ], "mac": { "category": "public.app-category.developer-tools", "entitlementsInherit": "build/app-entitlements.plist", "icon": "build/icon.png" }, "win": { "icon": "build/icon.ico", "requestedExecutionLevel": "highestAvailable", "target": [ { "target": "nsis", "arch": [ "x64" ] } ] }, "linux": { "target": [ { "target": "deb", "arch": [ "x64" ] } ], "icon": "build/icon.png", "maintainer": "主要贡献者", "description": "基于4.1.4配置" }, "nsis": { "oneClick": false, "allowElevation": true, "perMachine": false, "allowToChangeInstallationDirectory": true, "createDesktopShortcut": true, "createStartMenuShortcut": true, "uninstallDisplayName": "${productName}", "shortcutName": "${productName}", "artifactName": "${name}-${version}-setup.${ext}", "runAfterFinish": true } }, "devDependencies": { "electron": "^27.0.3", "electron-builder": "^24.6.4" }, "dependencies": { "electron-log": "^5.0.0", "electron-updater": "^6.1.4" } }
main.js
const { app, BrowserWindow, ipcMain } = require('electron') const { autoUpdater} = require('electron-updater') const os = require('os') const logger = require('electron-log') //打印log到本地 logger.transports.file.maxSize = 1002430 // 10M logger.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}]{scope} {text}' logger.transports.file.resolvePath = () => './operation.log' //打印在你安装的软件位置, autoUpdater.autoDownload = false //这个必须写成false,写成true时,我这会报没权限更新,也没清楚什么原因 // 将创建窗口独立成一个函数 function createWindow() { let mainWin = new BrowserWindow({ x: 100, y: 100, // 设置窗口显示的位置,相对于当前屏幕的左上角 show: false, // 默认情况下创建一个窗口对象之后就会显示,设置为false 就不会显示了 width: 800, height: 400, // maxHeight: 600, // maxWidth: 1000, minHeight: 200, minWidth: 300, // 可以通过 min max 来设置当前应用窗口的最大和最小尺寸 resizable: true, // 是否允许缩放应用的窗口大小 title: 'electron-tester', webPreferences: { enableWebSQL: false, webSecurity: false, spellcheck: false, nativeWindowOpen: true, nodeIntegration: true, contextIsolation: false, }, experimentalDarkMode: true, }) mainWin.loadFile('./src/index.html') //忽略无关代码 ipcMain.on('checkUpdate', () => { console.log('checkUpdate-->') //处理更新操作 const returnData = { error: { status: -1, msg: '更新时发生意外,无法进行正常更新!', }, checking: { status: 0, msg: '正在检查更新……', }, updateAva: { status: 1, msg: '正在升级……', }, updateNotAva: { status: 2, msg: '当前没有可用的更新...', }, } let platform = os.platform() === 'darwin' ? process.arch === 'x64' ? 'darwin' : 'darwin-arm64' : 'win32' let commitId = 'ab4f3c131bfec65670dd265549646b725f8ee649' //更新连接 autoUpdater.setFeedURL( // `https://devxz.dafenqi.law/lawdawn-api/api/update/${platform}/${commitId}` 'https://lawdawn-download.oss-cn-beijing.aliyuncs.com/win-2023-11-04-1' ) logger.error(['检查更新']) //更新错误事件 autoUpdater.on('error', function (error) { console.log('err-->', error) logger.error(['检查更新失败', error]) sendUpdateMessage(returnData.error) }) //检查事件 autoUpdater.on('checking-for-update', function () { sendUpdateMessage(returnData.checking) }) //发现新版本 autoUpdater.on('update-available', function (info) { console.log('info22-->', info) logger.info(['发现新版本', info]) sendUpdateMessage(returnData.updateAva) autoUpdater.downloadUpdate() }) //当前版本为最新版本 autoUpdater.on('update-not-available', function (info) { console.log('info11-->', info) setTimeout(function () { sendUpdateMessage(returnData.updateNotAva) }, 1000) }) //更新下载进度事件 autoUpdater.on( 'download-progress', function (progressObj, bytesPerSecond, percent, total, transferred) { console.log('progressObj-->', progressObj) mainWin.webContents.send('downloadProgress', progressObj) } ) //下载完毕 autoUpdater.on('update-downloaded', function (event, releaseObj) { //退出并进行安装(这里可以做成让用户确认后再调用) console.log('releaseNotes-->', releaseObj) autoUpdater.quitAndInstall() }) //发送消息给窗口 function sendUpdateMessage(text) { mainWin.webContents.send('message', text) } //发送请求更新 autoUpdater.checkForUpdates() }) mainWin.on('ready-to-show', () => { mainWin.show() }) // mainWin.on('closed', () => { // console.log('mainWin is closed') // mainWin = null // }) } process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true' app.on('ready', createWindow) app.on('window-all-closed', () => { console.log('all window is closed') app.quit() })
index.html
DocumentDocument...
test 检查更新 const fs = require('fs') const { ipcRenderer } = require('electron') document.getElementById('btn').onclick = () => { console.log('window-->', window) console.log('process-->', process, fs) navigator.mediaDevices .getUserMedia({ audio: true }) .then((stream) => { console.log('stream-》', stream) // Do something with the stream }) .catch((error) => { console.error('Failed to access microphone:', error) }) } document.getElementById('btn1').onclick = () => { //请求检查更新 ipcRenderer.send('checkUpdate') } //下载中收到的进度信息 ipcRenderer.on('downloadProgress', (event, data) => { // me.prograssStyle.width = data.percent.toFixed(2) + "%";//更新进度条样式 // me.stepText = "正在更新中(" + me.prograssStyle.width + ")..."; console.log('data-->', data) }) //监听请求更新响应,用来处理不同的事件 ipcRenderer.on('message', (event, data) => { switch (data.status) { case -1: alert(data.msg) break case 1: console.log('正在升级') break case 2: alert(data.msg) break } })
执行升级
执行yarn build之后,会生成安装包 和 yml文件
yml文件是内部做检测更新使用
version: 1.0.0 files: - url: electron-test-1.0.0-arm64-mac.zip sha512: YFebRa4hFb0eq7JBHtIbe6zpEm59b3uR0NaKJJaY5M7G7ZfCoFIWJl/N3cDzSvPK1vWSgeGTRwxteHmwV7PXBQ== size: 88974676 - url: electron-test-1.0.0.dmg sha512: ZToMM68na/NWbvYpqqEk3Ej0LzsDoyEYd9rW2qHIaq5FxU/HHNntzX2KiSv002WcLX6aQgLSgh37gvUJytvOpQ== size: 92423278 path: electron-test-1.0.0-arm64-mac.zip sha512: YFebRa4hFb0eq7JBHtIbe6zpEm59b3uR0NaKJJaY5M7G7ZfCoFIWJl/N3cDzSvPK1vWSgeGTRwxteHmwV7PXBQ== releaseDate: '2023-11-05T08:56:32.685Z'
我们需要把这三个文件放在 对象存储服务器上
只要提供的更新地址拼接上 latest-mac.yml文件的 可以访问到就可以
这样就可以做更新了
如果做测试,本地启动一个服务
//更新连接 autoUpdater.setFeedURL( 'http://127.0.0.1:5500/build' )
这里指向本地就可以,打包生层的文件放在build目录下 一样测试