

在 Electron 开发中,理解其底层架构是写出高性能、安全、可维护应用的关键。Electron 的核心思想非常清晰:用 Web 技术构建桌面应用。它通过将 Chromium(负责渲染 UI) 与 Node.js(负责系统能力) 深度集成,实现了这一目标。但这两者原本是相互隔离的运行环境——Chromium 出于安全考虑禁用了对本地系统的直接访问,而 Node.js 则专注于服务端/脚本任务。那么,Electron 是如何让它们“握手言和”的?本文将深入剖析其架构机制。
Electron 采用 多进程架构,这是其稳定性和安全性的基石。
BrowserWindow)require() 和系统权限。main.js 或 main.ts。// main.js
// main.js
const { app, BrowserWindow, ipcMain, webContents } = require('electron');
const path = require('path');
// 处理来自渲染进程的 IPC 请求
ipcMain.handle('read-file', async (event, filePath) => {
const fs = require('fs').promises;
try {
const data = await fs.readFile(filePath, 'utf8');
return data;
} catch (err) {
throw new Error(`无法读取文件: ${err.message}`);
}
});
ipcMain.handle('get-app-version', () => {
return app.getVersion();
});
// 创建主窗口
function createWindow() {
const win = new BrowserWindow({
width: 900,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'), // 关键:注入预加载脚本
contextIsolation: true, // 必须开启以保障安全
nodeIntegration: false, // 禁用直接 Node 访问
},
});
win.loadFile('index.html');
}
// 应用启动
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// 所有窗口关闭时退出(macOS 除外)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});BrowserWindow(或 <webview> 标签)对应一个独立的渲染进程。🔒 关键设计:默认情况下,渲染进程 无法直接访问 Node.js API(如
fs,path,child_process),这是为了防止网页代码直接操作用户系统,提升安全性。
<webview> 是 Electron 提供的一个特殊 HTML 标签,用于在应用内嵌入另一个独立的网页上下文。
<webview> 运行在自己的渲染进程中,与宿主页面隔离。https://example.com),常用于嵌入第三方服务(如聊天窗口、支付页面)。<webview src="https://www.github.com"
nodeintegration="false"
preload="./guest-preload.js">
</webview>⚠️ 注意:出于安全考虑,不要在
<webview>中启用nodeIntegration,除非你完全信任加载的内容。
虽然 Electron 基于 Chromium,但它并非“万能浏览器”。其 Web 能力存在明确边界:
能力 | 说明 |
|---|---|
最新 HTML/CSS/JS | 随 Chromium 版本更新(Electron 30+ 已支持 ES2023) |
Web APIs | Fetch、Canvas、WebGL、WebRTC、WebSocket 等 |
DevTools | 完整 Chrome DevTools 支持 |
自定义协议 | 可注册 app://、myapp:// 等协议 |
能力 | 原因/限制 |
|---|---|
Service Workers | 默认禁用(可通过 session 配置启用,但需谨慎) |
Push API / Notifications(Web 标准) | 被 Electron 原生通知 API 替代 |
某些 PWA 功能 | 如安装提示、后台同步,因桌面环境不同而无意义 |
跨域限制 | 本地 file:// 协议下 AJAX 请求受 CORS 限制(建议用 http-server 或自定义协议) |
自动更新机制 | 需依赖 Electron 自带的 autoUpdater,而非 Web 标准 |
require()。// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('myAPI', {
readFile: (path) => ipcRenderer.invoke('read-file', path),
getVersion: () => ipcRenderer.invoke('get-app-version')
});<!-- renderer -->
<script>
myAPI.getVersion().then(v => console.log('App version:', v));
</script>// main.js
ipcMain.handle('get-app-version', () => app.getVersion());✅ 这种方式既保留了 Web 的开发体验,又确保了系统调用的安全可控。
组件 | 角色 | 类比 |
|---|---|---|
主进程 | “大脑” | 应用的指挥中心 |
渲染进程 | “眼睛和手” | 用户看到的界面和交互 |
Chromium | 渲染引擎 | 浏览器内核 |
Node.js | 系统桥梁 | 连接操作系统的能力 |
IPC / Preload | 神经系统 | 安全传递指令与数据 |
Electron 的强大之处在于:它没有强行融合 Web 与 Native,而是通过清晰的进程边界和通信机制,让两者各司其职、安全协作。
📌 开发者忠告:
nodeIntegration: truecontextIsolation: true(默认已启用)如果你正在开发 Electron 应用,务必牢记:便利的背后是责任。正确理解架构,才能写出既强大又安全的桌面软件。