Electron 进程架构模型

Electron 的 JS 代码分布在两个独立的进程中:主进程(Node.js Runtime)和渲染进程(Chromium V8 Runtime)。它们不是"一个 JS 环境",而是两个完全隔离的 OS 进程,通过 IPC 协作。


一、Electron 的进程架构模型

scss 复制代码
┌─────────────────────────────────────────────────────────────┐
│                        操作系统                              │
│  ┌─────────────────────┐    ┌─────────────────────────────┐ │
│  │     主进程 (1个)      │    │      渲染进程 (N个)          │ │
│  │   Main Process       │    │    Renderer Process × N     │ │
│  │  ┌───────────────┐   │    │  ┌─────────────────────┐    │ │
│  │  │  Node.js      │   │    │  │   Chromium          │    │ │
│  │  │  Runtime      │   │◄──►│  │   ┌─────────────┐   │    │ │
│  │  │  (V8 + libuv) │   │IPC │  │   │  Blink 引擎  │   │    │ │
│  │  │               │   │    │  │   │  (DOM/CSS/JS)│   │    │ │
│  │  │  • 文件系统    │   │    │  │   └─────────────┘   │    │ │
│  │  │  • 网络请求    │   │    │  │   ┌─────────────┐   │    │ │
│  │  │  • 原生模块    │   │    │  │   │  V8 引擎    │   │    │ │
│  │  │  • 窗口管理    │   │    │  │   │ (隔离沙箱)   │   │    │ │
│  │  │  • 系统API    │   │    │  │   └─────────────┘   │    │ │
│  │  └───────────────┘   │    │  └─────────────────────┘    │ │
│  └─────────────────────┘    └─────────────────────────────┘ │
│         ▲                              ▲                    │
│         │      预加载脚本 (Preload)      │                    │
│         └──────────── 桥梁 ──────────────┘                    │
└─────────────────────────────────────────────────────────────┘

二、每个进程内部的线程模型

主进程(Main Process)

scss 复制代码
┌─────────────────────────────────────┐
│         主进程 (单个进程)             │
│  ┌─────────────────────────────┐   │
│  │      Node.js Event Loop     │   │
│  │         (libuv)             │   │
│  │  ┌─────┐ ┌─────┐ ┌─────┐   │   │
│  │  │ V8  │ │ 网络 │ │ 文件 │   │   │
│  │  │ 主线程│ │ IO  │ │ IO  │   │   │
│  │  └─────┘ └─────┘ └─────┘   │   │
│  │       ↓ 工作线程池 (libuv)   │   │
│  └─────────────────────────────┘   │
│  • 单线程事件循环(同标准 Node.js)   │
│  • 异步 IO 委托给 libuv 线程池      │
│  • 原生模块可能创建自己的线程        │
└─────────────────────────────────────┘

关键:主进程只有一个,是应用的入口和控制器。

渲染进程(Renderer Process)

scss 复制代码
┌─────────────────────────────────────────┐
│         渲染进程 (每个窗口一个)            │
│  ┌─────────────────────────────────┐   │
│  │        Chromium 多线程架构         │   │
│  │                                 │   │
│  │  ┌─────────┐  ┌─────────────┐   │   │
│  │  │ Browser │  │   Renderer  │   │   │
│  │  │ 线程    │  │   线程      │   │   │
│  │  │ (主线程)│  │ (合成/绘制)  │   │   │
│  │  └────┬────┘  └─────────────┘   │   │
│  │       │                          │   │
│  │  ┌────┴────┐  ┌─────────────┐   │   │
│  │  │   V8    │  │   IO 线程    │   │   │
│  │  │ 主线程   │  │ (网络/存储)   │   │   │
│  │  │ (执行JS) │  │             │   │   │
│  │  └─────────┘  └─────────────┘   │   │
│  │                                 │   │
│  │  • 还有 GPU 进程、扩展进程等       │   │
│  │    (Chromium 架构决定)            │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

关键:每个 BrowserWindow 创建一个独立的渲染进程。


三、你的 JS 代码到底跑在哪?

代码位置 运行在哪个 Runtime 能做什么 不能做什么
main.js (入口) Node.js Runtime (主进程) 文件系统、网络、创建窗口、系统API 直接操作 DOM
preload.js 混合环境 (渲染进程,但有 Node.js 上下文) require() 模块、ipcRenderer 不能直接访问页面 DOM(有隔离)
页面 JS (index.html 内) Chromium V8 (渲染进程,纯浏览器环境) DOM 操作、Web API、调用 window.api require()、fs、os 等 Node 模块

四、预加载脚本(Preload)的关键角色

这是 Electron 架构中最容易被误解的部分:

javascript 复制代码
┌─────────────────────────────────────────────┐
│              渲染进程                         │
│  ┌─────────────────────────────────────┐   │
│  │         上下文隔离 (ContextIsolation)  │   │
│  │  ┌─────────────┐  ┌─────────────┐   │   │
│  │  │  Preload    │  │   页面 JS    │   │   │
│  │  │  上下文      │  │   上下文     │   │   │
│  │  │             │  │             │   │   │
│  │  │ • 有 Node.js│  │ • 纯浏览器   │   │   │
│  │  │ • 可 require│  │ • 无 require │   │   │
│  │  │ • 可 IPC    │  │ • 只能 Web API│   │   │
│  │  └──────┬──────┘  └──────┬──────┘   │   │
│  │         │                │           │   │
│  │         └──── contextBridge ────────┘   │   │
│  │              (安全暴露 API)               │   │
│  └─────────────────────────────────────┘   │
└─────────────────────────────────────────────┘
javascript 复制代码
// preload.js --- 运行在渲染进程,但有 Node.js 能力
const { contextBridge, ipcRenderer } = require('electron')

// 把 ipcRenderer 的能力安全地暴露给页面 JS
contextBridge.exposeInMainWorld('electronAPI', {
  readFile: (path) => ipcRenderer.invoke('fs:readFile', path),
  onUpdate: (callback) => ipcRenderer.on('update', callback)
})

// 页面 JS 中:
// window.electronAPI.readFile('/path') → 发 IPC → 主进程处理 → 返回结果

关键洞察:

  • Preload 和页面 JS 不在同一个 V8 上下文 ,但通过 contextBridge 可以安全通信。
  • 这是 Electron 的安全架构核心------防止不受信任的页面代码直接访问系统能力。

五、协作模型:消息流示例

javascript 复制代码
用户点击按钮 (渲染进程)
    │
    ▼
页面 JS: window.electronAPI.saveFile(data)
    │
    ▼
Preload: ipcRenderer.invoke('dialog:save', data) ──┐
    │                                               │
    ▼                                               │
V8 序列化消息 ──────► Chromium IPC 管道 ────────────┤
    │                                               │
    ▼                                               │
操作系统内核 IPC ─────► 主进程接收                   │
    │                                               │
    ▼                                               │
主进程: ipcMain.handle('dialog:save', async (e, data) => {
    const { filePath } = await dialog.showSaveDialog()
    await fs.writeFile(filePath, data)
    return { success: true }
})
    │
    ▼
结果反向通过 IPC 返回 ──► Preload ──► 页面 JS Promise resolve

六、与 React Native 的对比(回应你之前的类比)

维度 React Native Electron
JS 运行位置 单个进程内的 JS 引擎(Hermes/JSC) 两个独立进程(主进程 Node.js + 渲染进程 Chromium V8)
原生通信 JSI / Bridge(同进程内存共享或异步) IPC(跨进程消息,必然序列化)
JS 线程数 1 个 JS 线程 + 原生模块线程 主进程 1 个 V8 + 每个窗口 1 个 V8
渲染 Yoga 布局 + 平台原生组件 Chromium Blink 引擎直接渲染
安全模型 相对宽松(同进程) 严格进程隔离 + ContextIsolation

七、一句话总结

Electron 的 JS 代码"分身"运行在两个世界:主进程是"拥有系统权限的 Node.js 后端",渲染进程是"被沙箱隔离的 Chromium 前端"。它们通过 IPC 像微服务一样协作,预加载脚本是两者之间的安全网关。这不是"一个 JS 环境",而是"两个独立运行时通过消息协议协作"的分布式架构。

相关推荐
wangruofeng42 分钟前
AI Models 1.1.0 发布,查大模型价格、对比模型和找 API 地址
前端·aigc·ai编程
wangruofeng1 小时前
给前端开发者的 100 个设计参考网站
前端·设计
星栈4 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技4 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户47949283569154 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
风骏时光牛马7 小时前
生成一个AI多模态标题,仅输出一条标题,无额外文字、问句、备选、配图、文案等任何附加内容,不需要其他的任务服务 只要标题。
前端
wangruofeng7 小时前
从 GIF 到 AVIF:网页图片格式演进与 2026 年选型指南
前端·架构
清晨Coding8 小时前
为什么用 React Developer Tools 查看组件树这么乱?
前端·react.js
鶴哥只手遮天8 小时前
《Electron 45.2.3 内核解剖》第 4 章 补丁体系:380 个补丁改了什么
前端·electron
FungLeo11 小时前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构