使用的是electron-vite进行快速搭建项目
一.环境搭建
1.初始化项目
首先全局安装 pnpm(非必须)
1 | npm i pnpm -g |
使用 electron-vite 脚手架创建项目
1 | pnpm create @quick-start/electron |
并安装依赖包
1 | pnpm install |
运行项目,接着就能看到新的 electron 应用
1 | npm run dev |
如果需要,可以去除打包前 ts 检查。将 package.json 文件的”build”: “npm run typecheck && electron-vite build”改成”build”: “electron-vite build”
打包成 win 系统安装包
1 | npm run build:win |
打包有可能报错:Sub items Errors: 2
解决方式:使用管理员身份运行 PowerShell,在项目目录执行打包命令;或者以管理员身份运行 vscode
参考文章:
electron builder 打包时,出现 errorOut=ERROR: Cannot create symbolic link
2.编辑器配置
1.vscode 安装并启用 eslint 和 prettier 插件
2.vscode 编辑器的 settings.json 也要配置格式化
1 | "editor.formatOnSave": true, // 保存时格式化 |
3.项目根目录.vscode 文件夹的 settings.json 也要配置对 vue 文件的格式化
1 | "[vue]": { |
二.快速开始
Electron 应用程序的入口都是 main 文件(在 package.json 指定),这个文件控制了主进程,它运行在一个完整的 Node.js 环境中,负责控制应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程
使用 BrowserWindow 创建和管理窗口
1 | const mainWindow = new BrowserWindow({ |
控制缩放比例
1 | // 控制拖放比例,1代表1:1 |
开启控制台
1 | // 开发环境控制台自动开启 |
三.进程模型
1.多进程模型
每个标签页在自己的进程中渲染
2.主进程
Electron 的主进程是一个拥有着完全操作系统访问权限的 Node.js 环境
3.渲染器进程
应用中的每个页面都在一个单独的进程中运行,这些进程被称为渲染器(renderer)进程
Electron 的主进程和渲染进程有着清楚的分工并且不可互换,渲染器进程要想与 Node.js 和 Electron 的原生桌面功能进行交互,需要通过进程进程间通信(IPC)
4.预加载脚本
预加载脚本可以将 Electron 的不同类型的进程桥接在一起,在渲染器加载网页之前注入。可以通过 contextBridge 将特权 API 暴露至渲染进程中。
预加载脚本与其所附着的渲染器在共享着一个全局 window 对象,但并不能从中直接附加任何变动到 window 之上,因为 contextIsolation 是默认的
语境隔离(Context Isolation)意味着预加载脚本与渲染器的主要运行环境是隔离开来的,以避免泄漏任何具特权的 API 到您的网页内容代码中.
因此需要使用 contextBridge 模块来安全地实现交互。但并不是 contextBridge 就是一定安全的,应该避免暴露没有任何参数过滤的特权 API
1 | // 错误使用,不安全 |
四.进程通信
可以使用 Electron 的 ipcMain 模块和 ipcRenderer 模块来进行进程间通信(IPC)
模式 1:渲染器进程到主进程(单向)
可以使用 ipcRenderer.send API 发送消息,然后使用 ipcMain.on API 接收
渲染器进程:
1 | <script setup lang="ts"> |
预加载脚本:
1 | contextBridge.exposeInMainWorld("electronAPI", { |
主进程:
1 | app.whenReady().then(() => { |
模式 2:渲染器进程到主进程(双向)
可以通过将 ipcRenderer.invoke 与 ipcMain.handle 搭配使用来完成
渲染器进程
1 | <script setup lang="ts"> |
预加载脚本:
1 | contextBridge.exposeInMainWorld("electronAPI", { |
主进程:
1 | async function handleFileOpen() { |
模式 3:主进程到渲染器进程
可以通过将 webContents.send 与 ipcRenderer.on 搭配使用来完成
主进程:
1 | const menu = Menu.buildFromTemplate([ |
预加载脚本:
1 | contextBridge.exposeInMainWorld("electronAPI", { |
渲染器进程:
1 | <script setup lang="ts"> |