跳到主要内容

Electron 教程

Electron 是一个开源框架,让你能够使用 JavaScript、HTML 和 CSS 构建跨平台的桌面应用程序。通过将 Chromium 和 Node.js 嵌入到其二进制文件中,Electron 允许你维护一个 JavaScript 代码库,并创建可在 Windows、macOS 和 Linux 上运行的跨平台应用程序。

什么是 Electron

Electron 本质上是一个桌面应用开发框架,它将 Web 技术与原生系统能力结合起来。你可以把它理解为:一个浏览器内核加上 Node.js 运行时,再配上一套原生 API。

核心组成

Electron 由三个主要部分组成:

  1. Chromium:负责渲染网页内容,提供现代浏览器的所有能力
  2. Node.js:提供文件系统访问、网络请求等后端能力
  3. Native API:提供操作系统原生功能,如窗口管理、菜单、托盘图标等

这种组合让 Web 开发者能够用熟悉的技术栈开发真正的桌面应用,而不需要学习 C++、Objective-C 或其他原生开发语言。

Electron 能做什么

Electron 可以构建各种类型的桌面应用:

  • 开发工具:Visual Studio Code、Atom 编辑器
  • 通讯软件:Slack、Discord、微信开发者工具
  • 媒体播放器:网易云音乐桌面版
  • 设计工具:Figma 桌面版
  • 笔记应用:Notion、Typora
  • 游戏平台:Steam 客户端的部分功能

进程模型

理解 Electron 的进程模型是开发 Electron 应用的基础。Electron 采用多进程架构,这与 Chromium 的设计一致。

为什么采用多进程

早期的浏览器采用单进程架构,所有功能都在一个进程中运行。这种设计存在严重问题:一个网页崩溃或卡死会影响整个浏览器。现代浏览器采用多进程架构,每个标签页运行在独立的进程中,相互隔离,一个页面的问题不会影响其他页面。

Electron 继承了这种架构,提供了更好的稳定性和安全性。

主进程

每个 Electron 应用有且只有一个主进程。主进程是应用的入口点,它运行在 Node.js 环境中,可以访问所有 Node.js API。

主进程的主要职责:

  1. 创建和管理窗口:使用 BrowserWindow 模块创建应用窗口
  2. 控制应用生命周期:使用 app 模块管理应用的启动、退出等
  3. 调用原生 API:访问菜单、对话框、托盘图标等系统功能
  4. 处理 IPC 通信:与渲染进程进行进程间通信
const { app, BrowserWindow } = require('electron')
const path = require('node:path')

function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}

app.whenReady().then(() => {
createWindow()

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})

这段代码展示了主进程的基本结构:创建窗口、处理应用生命周期事件。

渲染进程

每个 BrowserWindow 实例都会创建一个独立的渲染进程。渲染进程负责渲染网页内容,它运行的是标准的 Web 环境。

渲染进程的特点:

  1. Web 标准环境:可以使用 HTML、CSS、JavaScript
  2. 默认无 Node.js 访问权限:出于安全考虑,渲染进程默认不能直接使用 Node.js
  3. 通过 preload 脚本扩展能力:可以通过预加载脚本安全地暴露部分 Node.js 能力
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>我的应用</title>
</head>
<body>
<h1>Hello Electron!</h1>
<script src="./renderer.js"></script>
</body>
</html>

预加载脚本

预加载脚本(Preload Script)是连接主进程和渲染进程的桥梁。它在渲染进程加载网页内容之前执行,可以安全地暴露有限的 API 给渲染进程。

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
setTitle: (title) => ipcRenderer.send('set-title', title),
openFile: () => ipcRenderer.invoke('dialog:openFile')
})

通过 contextBridge.exposeInMainWorld,预加载脚本将特定的 API 暴露给渲染进程,同时保持上下文隔离,防止渲染进程直接访问 Node.js 和 Electron 的完整 API。

进程间通信

由于主进程和渲染进程是分离的,它们之间需要通过 IPC(Inter-Process Communication,进程间通信)来交换数据。

渲染进程到主进程(单向)

// 渲染进程
window.electronAPI.setTitle('新标题')

// 主进程
ipcMain.on('set-title', (event, title) => {
const webContents = event.sender
const win = BrowserWindow.fromWebContents(webContents)
win.setTitle(title)
})

渲染进程到主进程(双向)

// 渲染进程
const filePath = await window.electronAPI.openFile()

// 主进程
ipcMain.handle('dialog:openFile', async () => {
const { canceled, filePaths } = await dialog.showOpenDialog()
if (!canceled) {
return filePaths[0]
}
})

主进程到渲染进程

// 主进程
mainWindow.webContents.send('update-counter', 1)

// 渲染进程(通过预加载脚本暴露)
window.electronAPI.onUpdateCounter((value) => {
console.log('收到更新:', value)
})

Electron 与 Web 应用的区别

虽然 Electron 使用 Web 技术开发,但它与传统 Web 应用有重要区别:

特性Web 应用Electron 应用
运行环境浏览器独立进程
文件系统受限访问完全访问
系统集成有限深度集成
离线能力需要额外实现原生支持
更新机制服务端控制需要自己实现
安全模型沙箱隔离更大权限

Electron 应用拥有比 Web 应用更大的权限,这意味着开发者需要更加注意安全问题。

开发环境搭建

安装 Node.js

Electron 基于 Node.js,首先需要安装 Node.js。建议安装 LTS 版本,可以从 Node.js 官网 下载安装。

安装完成后,验证安装:

node -v
npm -v

创建项目

创建一个新的 Electron 项目:

mkdir my-electron-app
cd my-electron-app
npm init -y

安装 Electron:

npm install electron --save-dev

修改 package.json

{
"name": "my-electron-app",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron ."
}
}

项目结构

一个基本的 Electron 项目结构:

my-electron-app/
├── package.json
├── main.js # 主进程入口
├── preload.js # 预加载脚本
└── index.html # 窗口页面

运行应用

npm start

教程目录

入门基础

核心概念

窗口管理

系统集成

安全实践

打包发布

参考资料

学习建议

  1. 理解进程模型:这是 Electron 的核心概念,理解主进程和渲染进程的区别至关重要
  2. 掌握 IPC 通信:进程间通信是 Electron 开发的基础技能
  3. 重视安全:Electron 应用拥有较大权限,安全实践不可忽视
  4. 参考官方文档:Electron 官方文档质量很高,遇到问题首先查阅
  5. 动手实践:边学边写代码,加深理解

延伸阅读