2025了,你知道electron-vite吗?
electron-vite工程搭建
使用electron+vite
:https://cn.electron-vite.org/
electron-vite 需要 Node.js 版本 20.19+, 22.12+ 和 Vite 版本 5.0+
搭建第一个 electron-vite 项目
npm create @quick-start/electron@latest
✔ Project name: …
✔ Select a framework: › vue
✔ Add TypeScript? … No / Yes
✔ Add Electron updater plugin? … No / Yes
✔ Enable Electron download mirror proxy? … No / Yes
electron-vite 可以智能地为 Electron 的独特环境打包源代码。
主进程和预加载脚本: 无论是在开发还是生产中,这些都会被打包成 CommonJS 模块,并在 Node.js 环境中运行。
渲染器: 在开发过程中,electron-vite 会将 CommonJS / UMD 模块转换为 ES 模块以支持 HMR。在生产过程中,这些将被打包成 IIFE 模块,并在浏览器环境中运行。
项目结构
.
├──src
│ ├──main # 主进程
│ │ ├──index.ts
│ │ └──...
│ ├──out #构建输出
│ │ ├──main
│ │ └──preload
│ │ └──renderer
│ ├──preload #预加载脚本
│ │ ├──index.ts
│ │ └──...
│ └──renderer # with vue, react, etc.
│ ├──src
│ ├──index.html #渲染器
│ └──...
├──electron.vite.config.ts
├──package.json
└──...
主进程
是应用的核心,负责管理窗口、系统原生 API 调用和进程间通信(IPC)
需要写在主进程的内容:
窗口管理(BrowserWindow)
创建、控制应用窗口(大小、位置、菜单等)。
加载渲染进程(Vue/React 页面)。
// main.ts
import { app, BrowserWindow } from 'electron';
import path from 'path';function createWindow() {const win = new BrowserWindow({width: 1200,webPreferences: {preload: path.join(__dirname, '../preload/index.js'), // 预加载脚本},});// 开发环境加载 Vite 开发服务器,生产环境加载本地文件if (process.env.VITE_DEV_SERVER_URL) {win.loadURL(process.env.VITE_DEV_SERVER_URL);} else {win.loadFile(path.join(__dirname, '../renderer/index.html'));}
}app.whenReady().then(createWindow);
系统原生 API 调用
访问文件系统(fs)、系统对话框(dialog)、系统托盘(Tray)等。
import { dialog } from 'electron';// 示例:打开文件选择对话框
ipcMain.handle('open-file-dialog', async () => {const result = await dialog.showOpenDialog({properties: ['openFile'],});return result.filePaths[0];
});
进程间通信(IPC
通过 ipcMain 接收渲染进程的请求,执行敏感操作。
// 例如
import { ipcMain } from 'electron';
import fs from 'fs';// 暴露读取文件的方法给渲染进程
ipcMain.handle('read-file', (event, filePath) => {return fs.promises.readFile(filePath, 'utf-8');
});
应用生命周期管理
处理应用启动、退出、多窗口管理等。
app.on('window-all-closed', () => {if (process.platform !== 'darwin') app.quit();
});
渲染进程
渲染进程(Renderer Process) 是负责展示用户界面(UI)和运行前端代码(如 HTML、CSS、JavaScript 或 Vue/React 框架)的独立进程。每个 Electron 窗口(BrowserWindow)都对应一个独立的渲染进程,其行为类似于浏览器中的标签页,但具备更强的集成能力(通过配置可与 Node.js 交互)
渲染进程的核心特点:
- 基于 Chromium 引擎:每个渲染进程运行在独立的 Chromium 渲染环境中,支持现代前端技术(Vue/React/Angular、WebGL 等)。
- 默认隔离性:除非显式配置,否则渲染进程无法直接访问 Node.js 或系统资源(需通过主进程代理)。
- 多实例:每个 BrowserWindow 或 标签会创建独立的渲染进程。
主进程 vs 渲染进程
预加载脚本
预加载脚本会在渲染器的网页加载之前注入。如果你想向渲染器加入需要特殊权限
的功能,你可以通过 contextBridge
接口定义 全局对象。
预加载脚本的作用:
增强渲染器:预加载脚本运行在具有 HTML DOM APIs 和 Node.js、Electron APIs 的有限子集访问权限的环境中。
在主进程和渲染进程之间通信:使用 Electron 的 ipcMain 和 ipcRenderer
模块进行进程间通信(IPC)。
例如:
- 创建一个预加载脚本并通过 contextBridge.exposeInMainWorld 将 方法 或 变量 暴露给渲染器。
import { contextBridge, ipcRenderer } from 'electron'contextBridge.exposeInMainWorld('electron', {ping: () => ipcRenderer.invoke('ping')
})
- 将脚本附在渲染进程上,在 BrowserWindow 构造器中使用 webPreferences.preload 传入脚本的路径
import { app, BrowserWindow } from 'electron'
import path from 'path'const createWindow = () => {const win = new BrowserWindow({webPreferences: {preload: path.join(__dirname, 'preload.js'),},})ipcMain.handle('ping', () => 'pong')win.loadFile('index.html')
}app.whenReady().then(() => {createWindow()
})
- 在渲染器进程中使用暴露的函数和变量:
const func = async () => {const response = await window.electron.ping()console.log(response) // prints out 'pong'
}func()
沙盒
开启沙盒
特点:
渲染进程运行在严格隔离的环境,类似 Chrome 浏览器标签页:
- 无法直接访问 Node.js API(如 fs、path、child_process)。
- 无法使用 require 加载模块(除非通过预加载脚本注入)。
- 无法操作本地文件系统或执行系统命令。
安全机制
- 进程隔离:渲染进程与主进程完全隔离,依赖 IPC 通信。
- 上下文隔离(Context Isolation):默认启用,防止全局对象(如 window) 被篡改。
- 预加载脚本是唯一桥梁:通过 contextBridge.exposeInMainWorld 安全暴露有限 API。
关闭沙盒
特点:
渲染进程拥有完整 Node.js 访问权限:
- 可直接使用 require 加载模块(如 fs)。
- 能执行任意系统级操作(如读写文件、启动子进程)。
- 需要配合 nodeIntegration: true 和 contextIsolation: false 完全解锁能力。
风险
- 高危安全漏洞:如果 Vue 页面存在 XSS 漏洞,攻击者可注入代码删除文件、安装木马等。
- 恶意代码能绕过所有浏览器安全限制。
new BrowserWindow({webPreferences: {sandbox: false, // 关闭沙盒nodeIntegration: true, // 启用 Node.js 集成contextIsolation: false // 禁用上下文隔离(允许直接修改全局对象)}
});
Electron 官方推荐始终开启沙盒,除非有极端性能需求或明确可控的安全边界。
调试
可通过win.webContents.openDevTools({ mode: 'detach' });
或 ctrl+shift+i
打开调试控制台(像浏览器的控制台一样)
package.json命令解读
"scripts": {"start": "electron-vite preview", //启动开发服务器,支持热更新(HMR)"dev": "electron-vite dev", //在生产环境模式下预览应用(用于测试打包前的效果)"build": "npm run typecheck && electron-vite build", //执行类型检查后,使用 electron-vite 构建生产版本"postinstall": "electron-builder install-app-deps", //安装应用依赖(特别是原生模块)"build:unpack": "npm run build && electron-builder --dir", //electron-builder --dir 输出可执行文件依赖的原始文件结构"build:win": "npm run build && electron-builder --win", // 打包 Windows 安装包"build:mac": "npm run build && electron-builder --mac", //打包 macOS 应用"build:linux": "npm run build && electron-builder --linux" //打包 Linux 应用},
打包
打包时会自动下载对应版本的 Electron 二进制文件
如下:
为什么需要下载?
Electron 应用本质上是将你的代码与预编译的 Chromium 和 Node.js 运行时打包在一起。
打包工具(如 electron-builder 或 electron-packager)需要下载对应平台(如 Windows 64 位)和版本(如 v37.2.3)的 Electron 二进制文件作为基础。
这个文件的作用
下载的 ZIP 文件包含:
- Chromium 浏览器引擎(用于渲染 HTML/CSS/JS)
- Node.js 运行时(用于系统级 API 访问)
- Electron 框架本身(主进程 / 渲染进程通信等)
怎么解决下载太慢的问题
可以手动下载,并放到系统的缓存中,再次重新打包。
可将zip文件放置到C:\Users\Administrator\AppDatal\Locall\electron\Cache
目录下。如果找不到AppData文件夹,需在文件资源管理器中设置显示隐藏文件。
打包报错解决
解决了上面electron…zip的问题后,第一次打包可能还会遇到winCodeSign报错的,如下:
解决方式:
- 使用PowerShell 进行打包命令执行,如果不行试试下一个方法
- 同样的查看是否在
C:\Users\Administrator\AppDatal\Locall\electron\Cache
目录下有提示的winCodeSign的压缩包,如果没有,手动下载放置,同时将winCodeSign解压(保留原来压缩包的名字) 放置到C:\Users\用户名\AppData\Local\electron-builder\Cache\winCodeSign
再进行打包应该就可以了
等待进程结束
打包后的包
默认放置在dist目录下
外层安装包,双击自动安装并打开
免安装包:双击打开,外发需要整个文件夹的资源,否则不能打开。