Electron 基础
官方文档已经写的比较全了,所以并不会每个知识点都出现。
Electron 的主从进程模型是基本的常识。每个 Electron 应用有且只要一个主进程(Main Process)、以及一个或多个渲染进程(Renderer Process), 对应多个 Web 页面。更多更完整的请查看官方文档。
项目最小组成:

多进程模型
Electron 继承了来自 Chromium 的多进程架构,这使得此框架在架构上非常相似于一个现代的网页浏览器。electron 框架的机制是把主进程和渲染进程分开的,所以这就导致了 electron 项目通常也是把主进程和渲染进程分开处理。所以我们在查阅一些相关的开源项目的时候,为了方便项目管理通常会发现:
- 大部分项目处理自身 electron 主进程相关的内容会放在一个独立的文件夹里,比如,main。
- 而另外渲染页面及处理页面逻辑的内容也是放在一个独立的文件夹,比如,render。


可以发现,主线程和渲染线程都集成了 Native API 和 Node.js,渲染线程还集成 Chromium 内核,成功实现跨端开发。
PS:调试信息,主进程的只会在编辑器里控制 台显示。
主进程
任何 Electron 应用程序的入口都是 main 文件。这个文件控制了主进程,它运行在一个完整的 Node.js 环境中,负责控制您应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程。主进程在 Node.js 环境中运行,这意味着它具有 require 模块和使用所有 Node.js API 的能力。一个 Electron 应用有且只有⼀个主进程。
执行期间,Electron 将依据应用中 package.json 配置下 main 字段中配置的值查找此文件。即 main 字段对应的文件即为主进程的入口文件,基于主进程后再执行渲染进程。
主进程的主要目的是:
- 创建渲染进程,使用 BrowserWindow 模块创建和管理应用程序窗口。一个 BrowserWindow 里又可以承载多个 BrowserView。
- 管理原生 GUI,典型的窗口(BrowserWindow、Tray、Dock、Menu)等
- 控制应用生命周期
窗口管理
BrowserWindow 类的每个实例创建一个应用程序窗口,且在单独的渲染器进程中加载一个网页。您可从主进程用 window 的 webContent 对象与网页内容进行交互。
由于 BrowserWindow 模块是一个 EventEmitter,所以您也可以为各种用户事件(例如,最小化或最大化您的窗口)添加处理程序。
当一个 BrowserWindow 实例被销毁时,与其相应的渲染器进程也会被终止。
应用程序生命周期
主进程还能通过 Electron 的 app 模块来控制您应用程序的生命周期。该模块提供了一整套的事件和方法,可以使你添加自定义的应用程序行为(例如:以编程方式退出您的应用程序、修改程序坞或显示关于面板)。
渲染进程
每个 Electron 应用都会为每个打开的 BrowserWindow(与每个网页嵌入)生成一个单独的渲染进程。洽如其名,渲染器负责渲染网页内容。所以实际上,运行于渲染器进程中的代码是须遵照网页标准的(至少就目前使用的 Chromium 而言是如此)。
因此,一个浏览器窗口中的所有的用户界面和应用功能,都应与您在网页开发上使用相同的工具和规范来进行编写。
渲染器无权直接访问 require 或其他 Node.js API。
此刻,您或许会好奇:既然这些特性只能由主进程访问,那渲染器进程用户界面怎样才能与 Node.js 和 Electron 的原生桌面功能进行交互。而事实上,确实没有直接导入 Electron 內容脚本的方法。
PS:BrowserView 被用来让 BrowserWindow 嵌入更多的 web 内容。它就像一个子窗口,除了它的位置是相对于父窗口。
Preload 脚本
预加载(preload)脚本包含了那些执行于渲染器进程中,且先于网页内容开始加载的代码。这些脚本虽运行于渲染器的环境中,却因能访问 Node.js API 而拥有了更多的权限。
预加载脚本可以在 BrowserWindow 构造方法中的 webPreferences 选项里被附加到主进程。
// main.js
const { BrowserWindow } = require("electron");
//...
const win = new BrowserWindow({
webPreferences: {
preload: "path/to/preload.js",
},
});
//...
因为预加载脚本与浏览器共享 同一个全局 Window 接口,并且可以访问 Node.js API,所以它通过在全局 window 中暴露任意 API 来增强渲染器,以便你的网页内容使用。
虽然预加载脚本与其所附着的渲染器在共享着一个全局 window 对象,但您并不能从中直接附加任何变动到 window 之上,因为 contextIsolation 上下文隔离 是默认的。
语境隔离(Context Isolation)意味着预加载脚本与渲染器的主要运行环境是隔离开来的,以避免泄漏任何具特权的 API 到您的网页内容代码中。
取而代之,我们將使用 contextBridge 模块来安全地实现交互:
// preload.js
const { contextBridge } = require("electron");
contextBridge.exposeInMainWorld("myAPI", {
desktop: true,
});
// renderer.js
console.log(window.myAPI);
// => { desktop: true }
此功能对两个主要目的来说非常有用:
- 通过暴露 ipcRenderer 帮手模块于渲染器中,您可以使用 进程间通讯(inter-process communication, IPC) 来从渲染器触发主进程任务(反之亦然)。
- 如果您正在为远程 URL 上托管的现有 web 应用开发 Electron 封裝,则您可在渲染器的 window 全局变量上添加自定义的属性,好在 web 客户端用上仅适用于桌面应用的设计逻辑 。
进程间通信
非常重要
Webview
sandbox 进程沙盒化
在 Electron 中沙盒进程 大部分地 表现都与 Chromium 差不多, 但因为介面是 Node.js 的关系 Electron 有一些额外的概念需要考虑。
渲染器进程
当 Electron 中的渲染进程被沙盒化时,它们的行为与常规 Chrome 渲染器一样。 一个沙盒化的渲染器不会有一个 Node.js 环境。
因此,在沙盒中,渲染进程只能透过 进程间通讯 (inter-process communication, IPC) 委派任务给主进程的方式, 来执行需权限的任务 (例如:文件系统交互,对系统进行更改或生成子进程) 。
Preload 脚本
为了让渲染进程能与主进程通信,附属于沙盒化的渲染进程的 preload 脚本中仍可使用一部分以 Polyfill 形式实现的 Node.js API。 有一个与 Node 中类似的 require 函数提供了出来,但只能载入 Electron 和 Node 内置模块的一个子集:
- electron (仅限渲染器进程模块)
- 事件
- timers
- url
此外,以下 Node.js 基础对象也填充到了 preload 脚本的全局上下文中:
- Buffer
- process
- clearImmediate
- setImmediate