前端使用electron+vue3+ts搭建一個桌面端應用且可以熱更新
技術
字型加黑的是必要的技術,其他的庫是可以自由選擇的
- electron 13.0.0
- vue3 + ts
- electron-updater
- node 16.13.1
- element-plus
- less
- meansjs
搭建vue3專案
安裝vue-cli
如果有沒有安裝的話就全域性安裝
```javascript
npm install -g @vue/cli
```
建立vue3專案
跟vue2建立專案差不多,需要配置什麼自己去選擇,這兒我選擇的是ts開發
```javascript
vue create electron-vue3
```
啟動專案:
```
yarn serve
```
啟動成功以後,開始安裝electron;
安裝Electron
在此安裝的時候會叫你選擇版本,你根據自己的要求選擇就可(我的是13.0.0)
安裝依賴:
vue add electron-builder
啟動專案:
```
yarn electron:serve
```
我們在啟動的時候會報錯如下圖:
解決方案:
安裝:
yarn add [email protected]
找到background.ts檔案,將e修改
```javascript
try { await installExtension(VUEJS3_DEVTOOLS) } catch (e:any) { console.error('Vue Devtools failed to install:', e.toString()) }
```
然後再次啟動即可,在啟動的過程中有點慢,需要耐心等待;後續我會說怎麼解決
background.ts檔案修改
建立主程序檔案
在src隨意位置建立一個host檔案,可以在common檔案中隨意封裝很多檔案然後再host/index.ts檔案中引入使用即可
```javascript // src/host/index.ts
import { ipcMain} from 'electron'; export default (win:any)=>{ // 視窗最小化 ipcMain.on("window-minimize", function () { // 收到渲染程序的視窗最小化操作的通知,並呼叫視窗最小化函式,執行該操作 win.minimize(); });
// 視窗最大化
ipcMain.on("window-maximize", function () {
if (win.isMaximized()) {
win.restore();
} else {
win.maximize();
}
});
// 關閉視窗
ipcMain.on("window-close", function () {
win.hide();
win.close();
});
} ```
修改background.ts
由於太多了,不好描述我就直接貼上程式碼了,程式碼中有註釋大家也可以檢視;還有就是我們在上面說到的,專案啟動很慢的問題,在這而也是得到了解決的;
大致講解 * hout/index檔案是一個主程序接收發送檔案 * await installExtension(VUEJS3_DEVTOOLS)替換成session.defaultSession.loadExtension( path.resolve(__dirname, "../devTools/chrome"));會提高啟動速度,至於為什麼請自行百度 * 其他的new BrowserWindow引數做了一些調整,就沒怎麼修改了;好理解
```javascript 'use strict'
import { app, protocol, BrowserWindow,session } from 'electron'; import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'; // import installExtension, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer'; // 會導致啟動的時候很慢,所以不用 const isDevelopment = process.env.NODE_ENV !== 'production'; const path = require("path"); import host from '@/host/index';
// Scheme must be registered before the app is ready protocol.registerSchemesAsPrivileged([ { scheme: 'app', privileges: { secure: true, standard: true } } ]);
let win:any;
async function createWindow() { // Create the browser window. win = new BrowserWindow({ width: 1000, height: 600, minWidth: 800, minHeight: 600, // 不要邊框 frame: true, webPreferences: { webviewTag: true, // 禁止同源策略,避免 axios 無法使用 webSecurity: false, // Required for Spectron testing enableRemoteModule: !!process.env.IS_TEST, nodeIntegration: true, contextIsolation: false } })
// 主程序 host(win);
// 開發環境 if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string) if (!process.env.IS_TEST) win.webContents.openDevTools() // 開啟控制檯 } else { // 生產環境 createProtocol('app') // Load the index.html when not in development win.loadURL('app://./index.html') } }
// Quit when all windows are closed. app.on('window-all-closed', () => { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { app.quit() } })
app.on('activate', () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) createWindow() })
// This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', async () => { if (isDevelopment && !process.env.IS_TEST) { // Install Vue Devtools try { // await installExtension(VUEJS3_DEVTOOLS) // 會導致啟動的時候很慢 session.defaultSession.loadExtension( path.resolve(__dirname, "../devTools/chrome")); } catch (e:any) { console.error('Vue Devtools failed to install:', e.toString()) } } createWindow(); })
// Exit cleanly on request from parent process in development mode. if (isDevelopment) { if (process.platform === 'win32') { process.on('message', (data) => { if (data === 'graceful-exit') { app.quit() } }) } else { process.on('SIGTERM', () => { app.quit() }) } }
```
當你做到這兒的時候,你的啟動速度會賊快
然後我們開始配置vue.config.js;打包的時候需要的
vue.config.js
這裡的配置檔案我是根據初始化專案來進行配置的,如果你的專案沒有去修改初始檔案的名稱的話;可將以下程式碼複製進去即可。程式碼中我都寫了註釋的,大家需要修改什麼地方自己更改就好
注意的地方(重點):
- appId
- icon
- guid
- include
1、appId/guid需保持一致; 2、include重點中的重點,如果你需要熱更新的話;這個檔案一定要配置,不然你在解除安裝/更新後安裝軟體安裝不上;主要原因註冊機的問題。這個檔案最有一句程式碼也是要和appId一致的;
```javascript const { defineConfig } = require('@vue/cli-service');
module.exports = defineConfig({ transpileDependencies: true, lintOnSave: false, // 引入外掛不使用時不報報錯 configureWebpack: { externals: { 'electron': 'require("electron")' }, },
// 第三方外掛配置 pluginOptions: { // vue-cli-plugin-electron-builder 配置 electronBuilder: { nodeIntegration: true, // 設定應用主程序的入口 mainProcessFile: "src/background.ts", // 設定應用渲染程序的入口 rendererProcessFile: "src/main.ts", customFileProtocol: "../", // 打包選項 builderOptions: { // 解決的問題:在安裝到電腦後,系統通知無法工作 appId: "com.zhuhong.vue3", // 軟體id productName: "JSON工具", // 打包後的名稱 // windows系統相關配置 win: { // 應用圖示路徑(Windows 系統中 icon 需要 256 * 256 的 ico 格式圖片) icon: "./src/assets/login-icon.png", target: { target: "nsis", // 支援 64 位的 Windows 系統 arch: ["x64"], }, }, nsis: { // 如果為false,想要給電腦所有使用者安裝必須使用管理員許可權 allowElevation: true, // 是否一鍵安裝 oneClick: false, // 允許修改安裝目錄 allowToChangeInstallationDirectory: true, "guid": "com.zhuhong.vue3", // 軟體id "include": "./installer.nsh" }, }, }, }, })
```
根目錄建立installer.nsh檔案
```javascrpt !macro customInit
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\com.zhuhong.vue3"
!macroend
```
打包: ```javascrpt yarn electron:build
```
如果配置到這兒打包沒得問題,那麼你的專案基本上就行了;
最後呢?就是熱更新了;需要的可以繼續往下看
熱更新
安裝
javascript
yarn add electron-updater
新建JSPatch檔案
注意: * autoUpdater.setFeedURL一定要寫在外面,不然打包的時候會報錯 * url: process.env.VUE_APP_HOT_UPDATE, 不能這樣使用;否則打包也會報錯 * url連結地址事你存放打包檔案的地址 * 需要將此檔案引入background.ts檔案中 * 必須在app.on('ready', 函式中引用
```javascript // src/host/common/JSPatch.ts import { ipcMain } from "electron"; const { autoUpdater } = require("electron-updater");
autoUpdater.autoDownload = false; // 是否自動更新 autoUpdater.autoInstallOnAppQuit = true // APP退出的時候自動安裝
/ * 在開啟更新監聽事件之前設定 * 一定要保證該地址下面包含lasted.yml檔案和需要更新的exe檔案 / autoUpdater.setFeedURL({ provider: 'generic', url: 'https://', // 打包檔案存放地址 });
export default (win:any)=>{
// 傳送訊息給渲染執行緒 function sendStatusToWindow(status?:any, params?:any) { win.webContents.send(status, params); }
autoUpdater.on('checking-for-update', () => { sendStatusToWindow('Checking for update...'); }) autoUpdater.on('update-available', (info:any) => { // 可以更新版本 sendStatusToWindow('autoUpdater-canUpdate', info) })
autoUpdater.on('error', (err:any) => { // 更新錯誤 sendStatusToWindow('autoUpdater-error', err) }) // 發起更新程式 ipcMain.on('autoUpdater-toDownload', () => { autoUpdater.downloadUpdate() }) autoUpdater.on('download-progress', (progressObj:any) => { // 正在下載的下載進度 sendStatusToWindow('autoUpdater-progress', progressObj) }) autoUpdater.on('update-downloaded', () => { // 下載完成 sendStatusToWindow('autoUpdater-downloaded') })
// 退出程式 ipcMain.on('exit-app', () => { autoUpdater.quitAndInstall() })
// 重新檢查是否有新版本更新 ipcMain.on('monitor-update-system',()=>{ autoUpdater.checkForUpdates() })
// 檢測是否有更新 setTimeout(() => { autoUpdater.checkForUpdates(); }, 5000);
} ```
新建一個元件或者在app.vue中使用也可以jspatch
``javascript
<template>
<div class="jspatch">
<el-dialog
title="JSON工具更新中......"
v-model="showUpdater"
:close-on-click-modal="false"
:close-on-press-escape="true"
:show-close="false"
width="40%"
top="26vh"
center
>
<template v-if="downloadProcess">
<p> {{
當前:【${downloadProcess.transferred}】 / 共【${downloadProcess.total}】`}}
正在下載({{ downloadProcess.speed }})......
```
最後修改一哈vue.config.js就完成了
將以下程式碼複製到vue.config.js的builderOptions物件中即可
javascript
publish: [
{
provider: "generic",
url: 'https:', // 打包檔案地址,與以上鍊接需相同
},
],
然後再次打包安裝測試;沒有問題就可以上線了
也可以檢視線上程式碼
以前的文章
今天的分享就到這兒了,期待這個文章對你有幫助!