Electron 进程模型

164 阅读2分钟

Electron 的进程模型是其架构的核心之一,它基于 Chromium 和 Node.js 的双重引擎运行环境。Electron 应用主要由两个类型的进程构成:


🧠 主进程(Main Process)

  • 职责

    • 控制应用生命周期(启动、退出、窗口创建等)。
    • 管理原生系统交互(菜单、通知、文件系统、原生对话框等)。
    • 加载渲染进程。
  • 特点

    • 每个 Electron 应用只有一个主进程。
    • 主进程运行在 Node.js 环境中,可以使用 Node.js API。
    • 主进程通过 BrowserWindow 创建页面(也就是渲染进程)。
  • 示例代码main.js):

    const { app, BrowserWindow } = require('electron');
    
    app.whenReady().then(() => {
      const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true,
          contextIsolation: false,
        }
      });
      win.loadFile('index.html');
    });
    

🖼 渲染进程(Renderer Process)

  • 职责

    • 渲染界面(HTML/CSS/JS)。
    • 响应用户交互。
    • 类似浏览器中的每一个标签页。
  • 特点

    • 每个 BrowserWindowwebview 都运行在各自独立的渲染进程中。
    • 默认情况下,渲染进程是被隔离的,不能直接使用 Node.js(出于安全考虑)。
  • 与主进程通信
    使用 ipcMain(主进程) 和 ipcRenderer(渲染进程) 模块进行通信。

    // 渲染进程
    const { ipcRenderer } = require('electron');
    ipcRenderer.send('my-message', 'Hello from renderer');
    
    // 主进程
    const { ipcMain } = require('electron');
    ipcMain.on('my-message', (event, arg) => {
      console.log(arg); // "Hello from renderer"
    });
    

⚙ 进程间通信(IPC)

  • 使用 ipcMainipcRenderer 实现主进程与渲染进程之间的异步通信。
  • Electron v12+ 开始推荐使用 contextBridge + preload.js 来安全暴露接口给渲染进程。

🧩 其他进程类型

1. Preload 脚本(预加载进程)

  • 是一种在渲染进程加载前运行的脚本,运行在与渲染进程相同上下文,但可以访问部分 Node.js API。

  • 用于建立主/渲染进程间的安全桥梁。

  • 示例:

    // preload.js
    const { contextBridge, ipcRenderer } = require('electron');
    
    contextBridge.exposeInMainWorld('api', {
      sendMsg: (msg) => ipcRenderer.send('msg', msg)
    });
    

2. 子进程(Child Process)

  • 可以通过 child_process 模块在主进程中启动额外的 Node 子进程。
  • 通常用于处理 CPU 密集型任务或长期运行的服务。

总结图示:

          Electron 应用
               |
         ┌─────────────┐
         │ 主进程 Main  │ ←→ 系统资源、窗口管理
         └─────────────┘
               |
        ┌───────────────┐
        │ 渲染进程 #1    │ ←→ 显示 UIHTML/CSS/JS)
        └───────────────┘
               |
        ┌───────────────┐
        │ 渲染进程 #2    │ ←→ 显示另一个窗口
        └───────────────┘
               ...