3. 主进程与渲染进程
这是什么:进程模型 = Electron 应用内部的两套角色:主进程(main process)和渲染进程(renderer process)。
为什么用:第 2 章的 main.js 和 index.html 其实跑在两个不同的"世界"里,分不清谁管什么,后面写 IPC、调系统能力就会一头雾水。
如何用:还是那个项目,往两个进程里各加一行代码,亲眼看到它们互不相通。
3.1 两套角色,各干各的
| 对比 | 主进程 | 渲染进程 |
|---|---|---|
| 入口 | main.js |
每个窗口加载的网页(index.html + 它的 js) |
| 数量 | 只有 1 个 | 每个窗口 1 个,可多个 |
| 环境 | Node.js(能 require('fs') 等) |
纯网页(默认没有 Node) |
| 职责 | 窗口、菜单、生命周期、系统能力 | 界面展示、用户交互 |
记忆方式:主进程是「管家」,渲染进程是「演员」——管家开门窗、采购(系统资源),演员只负责在台上表演(界面)。
3.2 主进程:能摸到 Node
在 main.js 的 app.whenReady() 里加一行:
const { app, BrowserWindow } = require('electron')
function createWindow() {
const win = new BrowserWindow({ width: 800, height: 600 })
win.loadFile('index.html')
}
app.whenReady().then(() => {
console.log('主进程启动,Node 版本:', process.versions.node)
createWindow()
})
app.on('window-all-closed', () => {
app.quit()
})
npm start 后看终端(不是窗口):
主进程启动,Node 版本: 22.x.x
主进程能直接用 process、fs、path 这些 Node 能力——所以它负责系统能力。
3.3 渲染进程:就是个网页
往 index.html 里临时加一行脚本:
<script>
console.log('渲染进程里 typeof process =', typeof process)
</script>
在窗口里按 F12 打开 DevTools 看 Console:
渲染进程里 typeof process = undefined
process 不存在——渲染进程默认碰不到 Node。这不是缺陷而是安全设计:你写的界面可能会加载外来内容,一旦网页有漏洞,绝不能让它直接读写用户的硬盘。
💡 想让窗口自动打开 DevTools 调试,建窗口时加一行
win.webContents.openDevTools()。
3.4 那界面想用系统能力怎么办?
两种老办法都不推荐:
- ❌ 开
nodeIntegration: true让渲染进程拿到 Node——官方文档明令警告有安全风险 - ❌ 用远程模块——已被新版 Electron 移除
正解是 preload 脚本:一个运行在渲染进程、但由你白名单指定能干什么的"中间人"。它怎么搭桥,就是第 5 章 IPC 的主角。
3.5 生命周期三个钩子(现在记住两个)
| 钩子 | 时机 | 常用做法 |
|---|---|---|
app.whenReady() |
初始化完成 | 建第一个窗口 |
window-all-closed |
所有窗口关闭 | Windows/Linux 退出应用 |
activate |
点任务栏图标(macOS) | 没窗口就补建一个 |
第 2 章 main.js 里的两段代码,现在你能看懂它们为什么那么写了。
❓ 常见翻车现场
Q1:在 index.html 的脚本里写 require('fs') 直接报错
原因:渲染进程默认没有 Node,require 未定义——这正是 3.3 演示的行为。
解决:不绕过它,系统能力一律让主进程代劳(第 5 章)。
Q2:console.log 写在 main.js 里,窗口里怎么都找不到输出
原因:主进程的 console.log 输出到启动它的终端,不进 DevTools。
解决:回终端看;分不清输出来自哪个进程,就在文案里标明"主进程/渲染进程"。
Q3:窗口关了程序还在后台跑
原因:window-all-closed 钩子没写 app.quit(),主进程还活着。
解决:对照 3.2 的完整 main.js 补上这两行。
💡 动手改
- 在主进程打印
process.platform,确认你的系统是win32/darwin/linux中的哪个 - 建窗口时加
win.webContents.openDevTools(),让 DevTools 随窗口自动打开 - 建两个窗口试试:把
createWindow()调用两次——注意渲染进程有几个了?
📦 本章小结
- 主进程 1 个:Node 环境,管窗口、生命周期、系统能力,日志在终端
- 渲染进程每窗口 1 个:纯网页环境,管界面,日志在 DevTools
- 渲染进程默认没有 Node——是安全特性不是 bug
- 桥梁用
preload,下一章先把界面做漂亮,第 5 章正式搭桥
下一章:界面就是网页 🐸