Electron 入门:从背景到 Vue3 桌面应用开发
前言
Electron 是一个开源框架,由 GitHub 开发,允许开发者使用 Web 技术(HTML、CSS、JavaScript)构建跨平台桌面应用程序。其核心组成可概括为:Chromium 提供强大的渲染引擎负责界面显示,Node.js 提供后端能力如文件系统和网络访问,Native APIs 则提供操作系统级别的功能如菜单、通知和托盘。
一、Electron 背景介绍
1. 起源与发展
Electron 最初名为 Atom Shell,是 GitHub 为其 Atom 编辑器项目在 2013 年开发的底层框架。2015 年更名为 Electron 并开源,随后被 Slack、Visual Studio Code、Discord 等知名应用采用。2022 年,底层升级至 Chromium 106 和 Node.js 16.16.0,并支持 Windows 沉浸式黑暗模式等新特性。
2. 核心特点
Electron 将 Chromium(浏览器内核)和 Node.js(服务器/系统能力)封装进一个桌面应用壳中,使开发者能够使用 HTML/CSS/JS 编写跨平台的桌面程序(支持 Windows、macOS、Linux)。其关键特点包括:
- 跨平台:一套代码可运行在 Windows、macOS、Linux 上。
- Web 技术驱动:使用 HTML、CSS、JavaScript 构建 UI,无需学习 C++、Objective-C 或 Java。
- Chromium + Node.js 结合:Chromium 提供现代化的 Web 渲染引擎(支持最新 Web API),Node.js 允许访问文件系统、网络、原生 API 等底层功能。
- 生态丰富:支持自动更新、打包安装(如 NSIS、DMG、AppImage),并被 VS Code、Figma、Trello Desktop 等流行应用使用。
3. 优势
Electron 的设计理念是“一次编写,到处运行”。主要优势包括:
- 上手快速:Web 开发者可以复用前端技能、组件和生态(如 React、Vue、Angular、TypeScript、CSS)。
- 跨平台支持:编写一次代码即可构建三个平台的应用程序。
- 强大的本地能力:直接访问文件系统、进程、系统 API,无需编写本地语言绑定。
- 生态成熟:拥有大量现成库、模板和打包工具(如 Electron Builder、Electron Forge)。
- 适合工具类应用:如编辑器、通信工具、生产力软件和调试工具。
4. 应用场景
典型应用场景包括开发工具/编辑器(如 VS Code、Postman)、即时通信/社交客户端(如 Discord、Slack)、跨平台桌面客户端、原型与内部工具(如公司内部运营工具和数据面板)。它不适合对 CPU/GPU/内存极度敏感、需要极致原生体验或移动端优先的项目。
5. Electron 能做什么
Electron 能够实现多种功能,例如打开窗口、菜单、系统托盘和通知;读写文件、操作本地数据库;调用本机命令、启动子进程;使用原生对话框、剪贴板、拖拽和全局快捷键;实现自动更新、热重载和打包分发;加载本地或远程网页,支持现代 Web 技术(如 WebGL、WebRTC);以及集成原生模块以接入硬件或系统功能。
二、Electron 架构
Electron 应用基于多进程架构,主要包括:
1. 主进程(Main Process)
主进程是 Electron 应用的入口,负责控制应用生命周期(启动、退出)、创建窗口和管理原生功能(如菜单、对话框)。它运行在 Node.js 环境中,使用 Electron API,关键模块包括 app(控制应用事件)、BrowserWindow(创建窗口)、dialog(文件/消息对话框)和 ipcMain(与渲染进程通信)。
2. 渲染进程(Renderer Process)
每个 BrowserWindow 对应一个渲染进程,负责 UI 渲染(HTML/CSS/JS),类似于浏览器标签页。它运行在 Chromium 环境中,支持 Web 技术,关键模块包括 ipcRenderer(与主进程通信)和 fetch/XMLHttpRequest(网络请求)。
进程通信(IPC):主进程和渲染进程通过 ipcMain 和 ipcRenderer 进行数据交换。安全注意事项包括:永远不要在渲染进程中直接开启 NodeIntegration(应设置为 nodeIntegration: false),默认关闭以防 XSS 导致任意系统命令执行;使用 contextIsolation + preload + contextBridge 暴露最小、受控的 API;对外部内容进行严格校验和沙箱处理;对文件路径、shell 命令等输入做严格校验以避免命令注入;尽量使用 CSP、禁用 eval 并避免不受信任的第三方脚本。
三、环境搭建(Vue3 + Electron)
1. 创建 Vue3 项目
使用 Vite 创建 Vue3 项目:
npm create vite@latest my-vue-electron-app -- --template vue
cd my-vue-electron-app
npm install
2. 安装 Electron 依赖
安装 Electron 和打包工具:
npm install electron --save-dev
npm install electron-builder --save-dev
3. 项目结构
项目基本结构如下:
my-vue-electron-app/
├── package.json
├── vite.config.js
├── src/ # Vue3 前端代码
├── main.js # Electron 主进程
├── preload.js # 预加载脚本(安全 IPC 通信)
└── index.html # Electron 渲染进程入口(可选)
四、配置 Electron 主进程
1. 创建 main.js(主进程)
在项目根目录创建 main.js,用于控制 Electron 窗口和 Vue3 应用:
const { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: false, // 禁用 Node.js 集成(安全考虑)
contextIsolation: true, // 启用上下文隔离
preload: path.join(__dirname, 'preload.js'), // 预加载脚本
},
});
// 开发环境加载 Vite 开发服务器
if (process.env.NODE_ENV === 'development') {
win.loadURL('http://localhost:5173');
win.webContents.openDevTools(); // 打开 DevTools(可选)
} else {
// 生产环境加载打包后的 Vue3 应用
win.loadFile(path.join(__dirname, '../dist/index.html'));
}
}
// Electron 初始化完成后创建窗口
app.whenReady().then(createWindow);
// 所有窗口关闭时退出应用(macOS 除外)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
// macOS 点击 Dock 图标时重新创建窗口
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
2. 创建 preload.js(预加载脚本)
用于安全地暴露 IPC 通信 API 给 Vue3 渲染进程:
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
// 示例:发送消息到主进程
sendMessage: (message) => ipcRenderer.send('message-from-vue', message),
// 示例:接收主进程消息
onMessage: (callback) => ipcRenderer.on('message-from-main', (event, data) => callback(data)),
});
五、配置 Vue3 与 Electron 通信
1. 在 Vue3 组件中使用 IPC
在 Vue3 组件(如 src/App.vue)中调用 Electron API:
<template>
<div>
<h1>Vue3 + Electron 桌面应用</h1>
<button @click="sendMessageToElectron">发送消息给 Electron</button>
<div v-if="messageFromElectron">
<p>来自 Electron 的消息: {{ messageFromElectron }}</p>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const messageFromElectron = ref('');
// 发送消息到 Electron 主进程
const sendMessageToElectron = () => {
window.electronAPI.sendMessage('Hello from Vue3!');
};
// 接收来自 Electron 的消息
onMounted(() => {
window.electronAPI.onMessage((data) => {
messageFromElectron.value = data;
});
});
</script>
2. 在 main.js 中处理 IPC 消息
修改 main.js,让 Electron 主进程接收并回复 Vue3 的消息:
const { ipcMain } = require('electron');
// 监听来自 Vue3 的消息
ipcMain.on('message-from-vue', (event, message) => {
console.log('来自 Vue3 的消息:', message);
// 回复消息给 Vue3
event.sender.send('message-from-main', 'Electron 收到你的消息了!');
});
六、打包 Vue3 + Electron 应用
1. 修改 package.json
在 package.json 中添加或修改相关配置:
{
"name": "my-vue-electron-app",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:5173 && electron .\"",
"electron:build": "npm run build && electron-builder"
},
"devDependencies": {
"electron": "^28.0.0",
"electron-builder": "^24.0.0",
"concurrently": "^8.0.0",
"wait-on": "^7.0.0"
},
"build": {
"appId": "com.example.vue-electron",
"productName": "Vue3 Electron App",
"win": { "target": "nsis" },
"mac": { "target": "dmg" },
"linux": { "target": "AppImage" }
}
}
2. 运行与打包
- 开发模式:运行
npm run electron:dev同时启动 Vue3 开发服务器和 Electron。 - 生产打包:运行
npm run electron:build,打包后在dist/文件夹中生成 Windows.exe、macOS.dmg和 Linux.AppImage安装包。
七、总结
本文介绍了 Electron 的背景、架构、环境搭建、配置通信和打包流程。关键步骤包括:使用 Vue3 创建前端项目,集成 Electron 主进程和预加载脚本以实现安全 IPC 通信,并通过 electron-builder 打包成跨平台安装包。开发时注意安全最佳实践,如禁用 nodeIntegration、使用 contextIsolation 和 contextBridge。