運用Electron+Vue3.2+TypeScript+Vite開發桌面端
Electron可以讓程式設計師重用Web的程式碼,使用HTML、CSS、JavaScript來構建桌面應用,並在不同平臺上使用。
Electron官網上說:“比你想象的更簡單”————“如果你可以建一個網站,你就可以建一個桌面應用程式。 Electron 是一個使用 JavaScript, HTML 和 CSS 等 Web 技術建立原生程式的框架,它負責比較難搞的部分,你只需把精力放在你的應用的核心上即可。”
Vue 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。目前 Vue 已經成為繼 Rect 之後最流行的前端開發框架。
我找到了一個外掛:vite-plugin-electron,可以很方便的幫我們把 electron 和 vue 結合起來,開發起來非常方便。
目錄結構設計
因為我們需要使用 Electron 和 vue 進行開發,因此我們把它們分開目錄儲存,基礎目錄結構如下:
- electron-main: 主程序目錄。
- electron-preload: 預載入程式碼目錄,主要是定義橋接通訊。
- 其他檔案: 也就是 vue 初始化後的目錄。
目錄結構這麼設計的原因是因為我們使用的 vite-plugin-electron 外掛需要使用這樣的目錄結構,目前還沒有提供設定修改。
初始化專案目錄
下面就開始初始專案:
yarn create vite electron-desktop --template vue-ts
先使用 vite 建立 vue 專案,然後我們再將 electron 嵌入到裡面。
初始化完成後,我們先做一個本地 yarn 源的配置,防止下載庫的時候出現異常。
配置.yarnrc
registry "https://registry.npm.taobao.org/" electron_mirror "https://npm.taobao.org/mirrors/electron/" electron_builder_binaries_mirror "http://npm.taobao.org/mirrors/electron-builder-binaries/"
配置完下載源後,就可以安裝 electron 了。
安裝Electron
yarn add -D electron electron-builder rimraf vite-plugin-electron electron-devtools-installer
- electron-builder: 打包工具。
- rimraf: 快速刪除檔案或目錄工具。
- vite-plugin-electron: vite 結合 electron 的庫,關於這個外掛可以參見 Vite 與 Electron 無縫銜接。
- electron-devtools-installer: electron 開發工具。
vite-plugin-electron 外掛是將 vite 和 electron 結合在一起的,可以讓我們非常方便的結合 electron 和 vue,需要做一些指定的配置。
初始化electron專案
可以參考 electron 官網的快速開始專案。
- 建立主程序目錄和檔案。
// electron-main/index.ts import { app, BrowserWindow } from 'electron'; import path from 'path'; const createWindow = () => { const win = new BrowserWindow({ webPreferences: { contextIsolation: false, nodeIntegration: true, preload: path.join(__dirname, '../electron-preload/index.js'), }, }); if (app.isPackaged) { win.loadFile(path.join(__dirname, '../index.html')); } else { // Use ['ENV_NAME'] avoid vite:define plugin const url = `http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`; win.loadURL(url); } }; app.whenReady().then(() => { createWindow(); 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(); }); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } });
需要注意引入的預載入檔案應該是打包後的 js 檔案,路徑和 ts 檔案路徑相同,只要型別改為 js 即可。
- 建立預載入目錄和檔案。
在預載入檔案中我們列印一下系統平臺。
// electron-preload/index.ts import os from 'os'; console.log(os.platform());
配置vite-electron
tsconfig.json
在 tsconfig.json 中監聽 electron 相關檔案和提示。
"include": [..., "electron-main/**/*.ts", "electron-preload/**/*.ts"],
vite.config.ts配置
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import * as path from 'path'; import electron from 'vite-plugin-electron'; import electronRenderer from 'vite-plugin-electron/renderer'; import polyfillExports from 'vite-plugin-electron/polyfill-exports'; export default defineConfig({ plugins: [ vue(), electron({ main: { entry: 'electron-main/index.ts', }, preload: { // Must be use absolute path, this is the limit of rollup input: path.join(__dirname, './electron-preload/index.ts'), }, }), electronRenderer(), polyfillExports(), ], build: { emptyOutDir: false, // 必須配置,否則electron相關檔案將不會生成build後的檔案 }, });
配置主程序和預載入指令碼地址。
package.json配置
{ "name": "electron-desktop", "private": true, "version": "1.0.0", "main": "dist/electron-main/index.js", "scripts": { "dev": "vite", "build": "rimraf dist && vite build && electron-builder" }, "dependencies": { "vue": "^3.2.25" }, "devDependencies": { "@vitejs/plugin-vue": "^2.3.1", "electron": "^18.2.0", "electron-builder": "^23.0.3", "electron-devtools-installer": "^3.2.0", "rimraf": "^3.0.2", "typescript": "^4.5.4", "vite": "^2.9.5", "vite-plugin-electron": "^0.4.3", "vue-tsc": "^0.34.7" } }
主要是增加入口檔案,因為 electron 還沒有原生支援 ts,因此目前還是必須載入 js 檔案,所以入口檔案我們配置為解析後的 js 檔案路徑:
dist/electron-main/index.js,然後修改執行指令碼,在 build 命令中增加 electron-builder 打包命令。
electron-builder打包配置
# package.json { ......, "build": { "appId": "com.electron.desktop", "productName": "ElectronVueVite", "asar": true, "copyright": "Copyright © 2022 XingXingZaiXian", "directories": { "output": "release/${version}" }, "files": [ "dist" ], "mac": { "artifactName": "${productName}_${version}.${ext}", "target": [ "dmg" ] }, "win": { "target": [ { "target": "nsis", "arch": [ "x64" ] } ], "artifactName": "${productName}_${version}.${ext}" }, "nsis": { "oneClick": false, "perMachine": false, "allowToChangeInstallationDirectory": true, "deleteAppDataOnUninstall": false } } }
electron-builder 的配置我們有一篇專門的文章介紹,這裡並沒有什麼特殊的配置,按照需求配置即可。
到這裡就配置好了所有的檔案,接下來我們執行開發命令看一看效果。
yarn run dev
然後我們執行打包命令看一看效果。
yarn run build
執行完後會生成兩個目錄:dist 和 release。
dist 目錄中生成的是前端打包檔案,release 中生成的是 electron 打包檔案,內容如下:
其中 win-uppacked 中生成的是無需安裝的執行檔案,將此目錄直接壓縮後就可以傳送給別人,解壓即可使用。ExectronVueVite_1.0.0.exe 檔案是安裝包,開啟會顯示安裝過程,執行完安裝過程後在系統的控制面板中的軟體列表中可以看到該軟體,也可以執行解除安裝。
開啟後就是正常的軟體介面。
我們建立好了專案結構,那麼在使用 Vue 開發 Electron 桌面應用的時候還有一個比較重要的知識點要了解,就是訊息通訊。在新版本的 electron 中,推薦使用上下文隔離方式進行內部程序通訊,electron 官網有很詳細的介紹和示例,這裡我們只介紹一種方式,其他的方式大家可以通過檢視官網示例來了解。
我們的示例是在 Vue 介面中顯示當前系統平臺。
註冊上下文隔離介面
在 electron-preload/index.ts 中新增如下程式碼:
import os from 'os'; import { contextBridge } from 'electron'; contextBridge.exposeInMainWorld('electronAPI', { platform: os.platform(), });
編寫上下文隔離介面的typescript型別宣告
通過 electron 註冊的上下文隔離介面會新增給 window 物件,但是原始的 window 物件並不存在這些介面和屬性,ts 就會報錯,這時就需要我們為其編寫ts型別宣告檔案.d.ts。
// src/types/global.d.ts export interface IElectronAPI { platform: string; } declare global { interface Window { electronAPI: IElectronAPI; } }
在Vue中呼叫介面
我們在 App.vue 中呼叫window.electronAPI.platform 介面,把系統平臺資訊顯示在介面上。
// src/App.vue <script setup lang="ts"> // This starter template is using Vue 3 <script setup> SFCs // Check out https://vuejs.org/api/sfc-script-setup.html#script-setup import HelloWorld from './components/HelloWorld.vue'; const platform = window.electronAPI.platform; </script> <template> <img alt="Vue logo" src="./assets/logo.png" /> <HelloWorld :msg="`Hello Vue 3 + TypeScript + Vite in ${platform}`" /> </template>
執行完以上步驟後,執行專案看一下效果。
- 13 個非常有用的 Python 程式碼片段,建議收藏!
- [科普文] 淺談 Function Programing 程式設計正規化
- 什麼是Pulsar函式流處理應用?
- Flask vs Django: 該如何選擇Python框架?
- 十個用圖表解釋JavaScript 閉包的面試題
- 漫談 CSS 方法論
- 超詳細的日常開發必備神器 HttpUtil
- 理想中的介面自動化專案你瞭解嗎?
- 讓我們一起聊聊 Django 框架
- Spring中欄位格式化的使用詳解
- 2022 年面向開發人員的七個優秀 Java IDE
- 開發一個禁止刪除 Namespace 的控制器
- Web1.0到Web3.0,網際網路是如何演進的?
- DDD概念複雜難懂,實際落地如何設計程式碼實現模型?
- 學會一招!如何利用 pandas 批量合併 Excel?
- 超硬核!11個非常實用的 Python 和 Shell 拿來就用指令碼例項!
- 還在用requests寫爬蟲嗎?這個庫效率提高一倍!
- 分散式程式設計工具Akka Streams、Kafka Streams和Spark Streaming大PK
- 工具類如何獲取到 Spring 容器中的 Bean?
- code-review之前端程式碼優化彙總