Electron 入门与核心架构
前言
Electron 是 GitHub 开源的桌面应用开发框架,2013 年以 atom-shell 之名诞生,2015 年更名为 Electron 并持续维护至今。它允许开发者使用 HTML、CSS、JavaScript 构建跨平台(Windows / macOS / Linux)桌面应用,著名的 VS Code、Slack、Postman、Figma 等产品均基于 Electron 开发。
Electron 的核心魅力在于:前端工程师无需学习 C++ 或 Swift,用熟悉的 Web 技术就能开发原生桌面应用。本文将深入剖析 Electron 的底层架构,并手把手搭建 Hello World 应用。
Electron 双引擎架构
Chromium + Node.js
Electron 实际上是一个「浏览器 + 服务器」的组合体:
┌──────────────────────────────────────────────────────┐
│ Electron 应用 │
├─────────────────────────┬────────────────────────────┤
│ 主进程 (Main) │ 渲染进程 (Renderer) │
│ ┌─────────────────┐ │ ┌────────────────────┐ │
│ │ Node.js 运行时 │ │ │ Chromium 浏览器 │ │
│ │ (原生 API 访问) │ │ │ (HTML/CSS/JS 渲染) │ │
│ └─────────────────┘ │ └────────────────────┘ │
│ ↑ │ ↑ │
│ 原生系统 API │ DOM / CSS │
└─────────────────────────┴────────────────────────────┘主进程(Main Process)是整个应用的入口点,运行 Node.js 环境,拥有完整的系统级 API 访问权限。渲染进程(Renderer Process)是应用窗口内的页面,运行 Chromium 内核,负责 UI 渲染。
进程分工
| 职责 | 主进程 | 渲染进程 |
|---|---|---|
| 窗口管理 | 创建销毁 BrowserWindow | 持有窗口实例 |
| 原生 API | dialog、Tray、Menu、App | 通过 IPC 调用主进程 |
| 文件系统 | 完整 fs 读写权限 | 受限(沙箱) |
| 网络请求 | 无限制 | 受 CSP 限制 |
| 生命周期 | 全应用唯一 | 可多个(多窗口) |
一个 Electron 应用只能有一个主进程,但可以有多个渲染进程(对应多个 BrowserWindow)。主进程崩溃会导致整个应用退出,而单个渲染进程崩溃只会影响对应窗口。
创建 Hello World 应用
环境要求
# Node.js >= 18.0
node -v # 建议使用 nvm 或 fnm 管理版本
# 包管理器(pnpm 推荐)
pnpm -v手动搭建(不依赖脚手架)
# 创建项目目录
mkdir electron-hello && cd electron-hello
pnpm init -y
# 安装 Electron(建议锁定版本)
pnpm add electron@35.2.0 -D
# 创建目录结构
mkdir -p src// src/main.js — 主进程入口
const { app, BrowserWindow } = require('electron');
app.whenReady().then(() => {
const win = new BrowserWindow({
width: 800,
height: 600,
title: 'Hello Electron',
webPreferences: {
// 安全配置,后续文章详述
nodeIntegration: false,
contextIsolation: true,
},
});
win.loadFile('index.html');
});
// 所有窗口关闭后退出(macOS 行为特殊处理)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});<!-- index.html — 渲染进程页面 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Hello Electron</title>
<style>
body { font-family: sans-serif; display: flex; justify-content: center;
align-items: center; height: 100vh; margin: 0; background: #f0f0f0; }
h1 { color: #333; }
</style>
</head>
<body>
<h1>Hello, Electron!</h1>
<p>你的第一个桌面应用正在运行。</p>
</body>
</html><!-- package.json -->
{
"name": "electron-hello",
"main": "src/main.js",
"scripts": {
"start": "electron .",
"dev": "electron . --enable-logging"
}
}# 启动应用
pnpm start使用 Electron Forge 脚手架(推荐)
手动搭建适合学习,但生产项目推荐使用 Electron Forge:
# 一键创建基于 Vite + TypeScript 的项目
pnpm create electron-app@latest my-app --template=vite-typescript
cd my-app
pnpm devForge 会自动配置好 electron、构建工具、开发服务器,并生成规范的目录结构。
BrowserWindow 基础配置
BrowserWindow 是 Electron 中最核心的类,用于创建和管理应用窗口。以下是常用配置项:
const { BrowserWindow } = require('electron');
const mainWindow = new BrowserWindow({
// 窗口尺寸
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
// 窗口标题
title: 'My Electron App',
// 是否显示窗口(用于后台任务)
show: false,
// 背景色
backgroundColor: '#ffffff',
// 是否使用系统边框窗口(false = 自定义标题栏)
frame: true,
// 透明窗口(需要 frame: false)
transparent: false,
// 窗口图标
icon: './assets/icon.png',
// Web 相关配置
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
sandbox: true,
preload: './preload.js',
},
});
// 窗口准备好显示时再显示(避免白屏闪烁)
mainWindow.once('ready-to-show', () => {
mainWindow.show();
});
// 加载页面
mainWindow.loadFile('index.html');
// 或加载远程 URL
// mainWindow.loadURL('https://example.com');
// 在 DevTools 中调试
mainWindow.webContents.openDevTools();窗口事件
mainWindow.on('close', (e) => {
// 阻止窗口关闭(例如:用户未保存时弹出确认)
if (hasUnsavedChanges) {
e.preventDefault();
mainWindow.destroy(); // 强制关闭时用
}
});
mainWindow.on('closed', () => {
// 窗口已销毁,清除引用
mainWindow = null;
});
mainWindow.on('maximize', () => console.log('窗口最大化'));
mainWindow.on('minimize', () => console.log('窗口最小化'));
mainWindow.on('unmaximize', () => console.log('窗口退出最大化'));多窗口管理
Electron 支持创建多个窗口,适合邮件客户端(收件箱窗口 + 邮件详情窗口)等场景:
const { BrowserWindow } = require('electron');
// 主窗口
function createMainWindow() {
const win = new BrowserWindow({ width: 1200, height: 800 });
win.loadFile('main.html');
return win;
}
// 详情窗口(子窗口)
function createDetailWindow(parent) {
const child = new BrowserWindow({
width: 600,
height: 400,
parent, // 关联主窗口
modal: true, // 模态窗口(阻塞主窗口交互)
show: false,
});
child.loadFile('detail.html');
child.once('ready-to-show', () => child.show());
return child;
}进程间通信基础
Electron 的主进程与渲染进程默认完全隔离,不能直接相互调用。两者通过 IPC(Inter-Process Communication) 通信,这是 Electron 最核心的机制,后续文章将单独详述。
一个简单的点击计数器示例:
// main.js — 主进程
const { ipcMain } = require('electron');
ipcMain.handle('get-count', () => count);
ipcMain.handle('increment', () => {
count += 1;
return count;
});// preload.js — 预加载脚本(后续详述)
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
getCount: () => ipcRenderer.invoke('get-count'),
increment: () => ipcRenderer.invoke('increment'),
});// index.html 中的渲染进程脚本
const btn = document.getElementById('counter');
btn.addEventListener('click', async () => {
const count = await window.electronAPI.increment();
btn.textContent = `点击次数: ${count}`;
});小结
- Electron = Chromium(渲染 UI)+ Node.js(系统级 API)
- 主进程是应用入口,渲染进程负责页面展示,两者通过 IPC 通信
BrowserWindow是创建窗口的核心类,支持丰富的配置选项- 生产项目推荐使用 Electron Forge 脚手架创建项目
下一篇文章我们将介绍 Electron Forge 开发环境配置,学习如何使用 Vite/Webpack 模板、热重载调试,以及 package.json 的关键字段含义。
评论
Written by
AI-Writer
Related Articles
Preload 脚本与上下文隔离
理解 Preload 脚本的执行时机、contextBridge 安全暴露 API、nodeIntegration 与 contextIsolation 配置组合,以及主进程与渲染进程的安全边界
Read More原生对话框与文件操作
使用 dialog.showOpenDialog、showSaveDialog、showMessageBox 原生对话框,Shell 模块打开外部链接和文件资源管理器,跨平台路径处理和用户数据目录访问
Read MoreElectron Forge 开发环境与项目配置
使用 Electron Forge 脚手架快速创建项目、配置 Vite/Webpack 构建、开发热重载调试、解析 package.json 关键字段与标准目录结构
Read More