目录

2025Electron-基础二进程模型三大核心

【2025】Electron 基础二(进程模型三大核心)

源代码仓库:

  1. 主进程 (Main Process)
  2. 渲染进程 (Renderer Process)
  3. 预加载脚本 (Preload Script)

假设你要开一家公司(开发一个桌面应用),这个公司需要三个核心角色:

  1. 董事长(主进程) :整个公司只有一个董事长,他掌握所有核心权力:

    • ✅ 决定公司什么时候开门/关门(应用启动退出)
    • ✅ 招聘新员工(创建新窗口)
    • ✅ 直接联系政府机关(调用系统级API)
    • ✅ 保管公司保险柜钥匙(访问本地文件)
  2. 普通员工(渲染进程) :每个员工负责一个窗口的接待工作:

    • 🖥️ 每人只负责一个办事窗口(每个窗口对应一个渲染进程)
    • 🎨 专门搞装修设计(负责界面UI展示)
    • 🔒 不能直接进保险库(默认不能访问敏感功能)
    • 💬 有事得打报告请示(通过IPC通信找董事长)
  3. 秘书(预加载脚本) :董事长安排在员工身边的助手:

    • 📞 帮员工转达需求给董事长(桥接通信)
    • 🛡️ 盯着员工别乱来(安全隔离)
    • 📋 只给员工有限的申请表(暴露有限API)

// renderer层
// 员工(渲染进程)的日常工作
function handleOpenFileClick() {
  // 不能直接操作文件,得找秘书帮忙
  window.API.sendRequest('open-file')
}
// preload层
// 秘书(预加载脚本)的工作手册
contextBridge.exposeInMainWorld('API', {
  sendRequest: (type) => {
    ipcRenderer.send('to-boss', type) // 打电话给董事长
  }
})
// main层
// 董事长(主进程)的权限
ipcMain.on('to-boss', (event, type) => {
  if (type === 'open-file') {
    const file = dialog.showOpenDialogSync() // 直接调用系统对话框
    event.sender.send('reply', file) // 把结果传回去
  }
})
// 员工收到回复后的操作
ipcRenderer.on('reply', (event, file) => {
  document.getElementById('file-path').textContent = file
})

Electron IPC通信:使用 invoke/handle 和 send/on 进行通信

特性invoke/handlesend/on
通信方向双向(需要响应)单向/双向(需手动回复)
返回值处理自动返回Promise需手动监听回复事件
错误处理自动传递reject错误需额外错误事件处理
代码简洁度⭐⭐⭐⭐⭐⭐
典型使用场景获取数据、执行操作并等待结果通知事件、状态推送、实时消息
// 渲染进程
const result = await ipcRenderer.invoke('read-file', '/path/to/file')

// 主进程
ipcMain.handle('read-file', async (event, path) => {
  return fs.promises.readFile(path, 'utf-8')
})
// 自动错误传递
try {
  await ipcRenderer.invoke('dangerous-operation')
} catch (error) {
  showErrorDialog(error.message)
}
// 顺序执行多个依赖操作
const user = await ipc.invoke('get-user', id)
const orders = await ipc.invoke('get-orders', user.id)
const analytics = await ipc.invoke('generate-report', orders)
// 渲染进程:不需要等待回复
ipcRenderer.send('window-minimize')

// 主进程
ipcMain.on('window-minimize', () => {
  mainWindow.minimize()
})
// 主进程:检测到新版本时广播
mainWindow.webContents.send('update-available', {
  version: '2.0.0',
  releaseNotes: '...'
})

// 渲染进程
ipcRenderer.on('update-available', (event, info) => {
  showUpdateDialog(info)
})
// 主进程:中转消息
ipcMain.on('chat-message', (event, msg) => {
  // 广播给所有窗口
  BrowserWindow.getAllWindows().forEach(win => {
    win.webContents.send('new-message', msg)
  })
})