1. 初识 Electron
大家好,我是你们这节课的向导。今天咱们聊聊Electron——这个让我从原生开发“叛逃”过来的框架。
先说说我自己的经历。几年前我还在用C++写桌面应用,每次改个UI都要重新编译,那叫一个痛苦。后来接触了Electron,说实话,第一反应是“这不就是个浏览器套壳吗?”但真正用起来才发现,事情没那么简单。
什么是Electron?
Electron,说白了就是一个让你用HTML、CSS和JavaScript写桌面应用的框架。它把Chromium和Node.js打包在一起,让你既能操作DOM,又能调用系统API。
你想想看,以前写桌面应用得学C#、C++或者Java Swing。现在呢?前端工程师直接上手。我团队里有个刚毕业的小伙子,三天就写出了第一个原型。这在原生开发里根本不敢想。
核心公式:
Electron = Chromium(渲染引擎) + Node.js(运行时) + 原生API(系统能力)
Electron的发展历程
Electron的故事要从2013年说起。GitHub团队当时想做个跨平台的代码编辑器,叫Atom。他们试了各种方案,都不满意。最后干脆自己造了个轮子——也就是Electron的前身,当时叫Atom Shell。
2014年,项目开源并改名为Electron。我记得那时候文档还很不全,踩坑全靠翻源码。但社区发展特别快,2015年Slack、Visual Studio Code这些大项目就开始用了。
到了2017年,Electron已经成了GitHub上最热门的项目之一。现在呢?全球有超过百万的应用在用Electron。从Discord到WhatsApp,从Figma到Twitch,你每天用的工具里,可能有一半都是Electron写的。
| 年份 | 里程碑 |
|---|---|
| 2013 | GitHub启动Atom编辑器项目,开发Atom Shell |
| 2014 | Atom Shell更名为Electron,正式开源 |
| 2015 | Slack、VS Code等重量级应用采用Electron |
| 2017 | Electron成为GitHub增长最快的开源项目之一 |
| 2020 | Electron 10发布,支持Chrome 85和Node.js 14 |
| 2024 | Electron 30+版本,生态成熟,社区活跃 |
为什么选择Electron?
这个问题我经常被问到。说实话,没有银弹。但Electron在几个场景下确实很香:
- 团队技术栈统一:前端团队直接上手,不用重新招人。我见过一个公司,整个桌面端就两个人维护,全是前端转过来的。
- 快速迭代:改个UI不用编译,热重载直接看效果。我曾经一天迭代了十几个版本,这在原生开发里根本不可能。
- 跨平台:一套代码跑Windows、macOS、Linux。你想想看,维护三套原生代码是什么体验?我经历过,那叫一个酸爽。
- 生态丰富:npm上百万个包随便用。需要操作文件?有fs-extra。需要数据库?有better-sqlite3。需要网络请求?axios直接上。
我的建议:
如果你的应用需要频繁更新UI、团队以Web开发者为主、或者预算有限,Electron是很好的选择。但如果你要做高性能图形处理、3D渲染或者系统级驱动开发,还是老老实实用原生吧。
Electron的核心架构概览
嗯,这里要注意。Electron的架构其实不复杂,但很多人一开始会搞混。核心就两个进程:主进程和渲染进程。
主进程(Main Process)
主进程是应用的入口,负责管理窗口、系统菜单、托盘图标、原生对话框等。它运行在Node.js环境里,可以调用所有系统API。每个Electron应用只有一个主进程。
渲染进程(Renderer Process)
每个窗口就是一个渲染进程。它运行在Chromium环境里,负责显示页面。你可以把它理解成一个浏览器标签页。每个窗口都有自己的渲染进程,互不干扰。
为什么会这样设计?说白了就是安全考虑。渲染进程崩溃了,不会影响其他窗口。我曾经遇到过一个问题:一个页面里有个死循环,结果整个应用卡死了。后来把复杂计算放到主进程里,渲染进程只负责展示,问题就解决了。
进程间通信(IPC)
主进程和渲染进程不能直接访问对方的数据。它们通过IPC(Inter-Process Communication)来通信。Electron提供了ipcMain和ipcRenderer两个模块,专门干这个事。
// 主进程
const { ipcMain } = require('electron')
ipcMain.handle('get-user-data', async (event, userId) => {
// 这里可以调用数据库、文件系统等
return { name: '张三', age: 28 }
})
// 渲染进程
const { ipcRenderer } = require('electron')
async function loadUserData() {
const data = await ipcRenderer.invoke('get-user-data', '123')
console.log(data) // { name: '张三', age: 28 }
}
避坑指南:
我曾经犯过一个错误:在渲染进程里直接用了Node.js的fs模块。结果在打包后,有些用户的电脑上报错。后来才发现,渲染进程默认是禁用Node.js集成的。需要手动设置nodeIntegration: true,但出于安全考虑,我建议用preload脚本暴露有限的API。
除了主进程和渲染进程,Electron还有几个重要的概念:
- preload脚本:在渲染进程加载前执行,可以安全地暴露部分Node.js API给渲染进程。我一般用它来做IPC通信的桥梁。
- BrowserWindow:创建和管理窗口的核心类。可以设置窗口大小、位置、是否可调整、是否全屏等。
- app模块:控制应用生命周期。比如ready事件、before-quit事件等。
好了,这一章就到这里。Electron的核心架构其实不复杂,但理解主进程和渲染进程的关系很重要。下一章我们会深入主进程,看看它到底能做什么。
记住一句话:主进程管系统,渲染进程管界面。两者通过IPC沟通。这个思路贯穿整个Electron开发。