Electron 官网导读、版本策略与首个 Hello-Electron 应用
概述
这一节把 Electron 从“听说过”推进到“真正跑起来”。先去官网读懂它的定位与阅读路线,再讲清运行时底座(Chromium + Node.js)、版本支持窗口、本地 Node 与运行时 Node 的区别,最后落地一个最小可运行的 Hello Electron 应用,并解决国内安装慢这个最现实的问题。它承接上一节“为什么选 Electron”,是桌面端工程实践的第一块砖。
学习目标
- 能复述 Electron 的核心定位:用 JavaScript / HTML / CSS 构建跨平台桌面应用,聚焦桌面端而非移动端。
- 理解 Electron 的运行时底座是 Chromium + Node.js,所以它是一个完整运行时,而不只是“网页套壳”。
- 掌握版本策略:大版本迭代很快,但真正该关注的是官方支持窗口(最近 3 个稳定大版本),而非盲目追新。
- 区分本地 Node.js 与 Electron 内置 Node.js:前者用于开发与构建,后者才是应用运行时真正执行代码的环境。
- 建立“先 Tutorial、再 Releases、最后查 API”的官网阅读顺序。
- 能独立跑起一个最小 Hello Electron 应用,并理解主进程创建窗口、加载本地 HTML 这条最小闭环。
- 知道国内安装慢的本质是下载 Electron 二进制,掌握换源与配置镜像两类加速思路。
一、先读懂 Electron 的官网定位
打开 Electron 官网,最醒目的一句定位就是“用 JavaScript、HTML、CSS 构建跨平台桌面应用”。这句话一下子把它和 Tauri、Flutter 区分开:Electron 聚焦的是桌面端(Windows / macOS / Linux),而不是优先冲向移动端;它的核心入口仍然是前端三剑客。官网还强调了三个身份标签:Web technologies(技术栈对前端友好)、Cross platform(三端目标)、Open source(成熟开源生态)。
对前端同学,这个定位本身就是最大吸引力——你不必换语言,就能把已有的 Web 能力延伸到桌面。课程也再次点明它与 Tauri / Flutter 的差异:后两者要么换语言栈(Rust / Dart),要么仍在向移动端扩张;Electron 则把桌面端作为主战场,前端同学迁移成本最低。理解这一点,后面所有“为什么用 Electron”的判断才有根。
二、运行时底座是 Chromium + Node.js
Electron 内部嵌入了 Chromium 和 Node.js:Chromium 负责渲染网页界面,Node.js 负责系统能力与后端式能力接入。这就是为什么你在 Electron 里会感觉“既熟悉又不一样”——页面层还是 HTML / CSS / JS,但它还能调用系统级 API(自动更新、安装器、菜单、系统通知、崩溃上报等)。所以它不是一个浏览器标签页,而是一个把 Node 与 Chromium 真正装进应用运行时的完整环境。
也正是因为这个双底座,后续所有主进程、渲染进程、IPC 的内容才有了依托。可以用一个类型把它记下来:
type ElectronRuntime = {
ui: "Chromium"
system: "Node.js"
bundlingNote: "完整运行时,非网页套壳"
}这也解释了为什么 Electron 的包体积会明显大于纯前端 Web 应用:它把一整个浏览器内核和 Node 运行时都打进了安装包。这是能力的代价,也是后面讲打包与体积优化时的核心矛盾点。
三、版本策略:追新不如看支持窗口
Electron 的大版本迭代非常快,从个位数版本到现在二十几、三十几,节奏肉眼可见。但课程真正想提醒的是:不要只盯着版本号变快,更要看“哪些版本还被官方支持”。官方目前明确只支持最近 3 个稳定大版本;一旦你用得超出支持窗口,后续遇到启动、平台兼容、安全问题时,就很难再等到官方修复。
因此“稳定且受支持”通常比“永远最新”更重要。像 VS Code 这类大项目也会略滞后,但仍保持在支持窗口附近——这个取舍对业务项目同样成立。判断自己是否还在窗口内,最直接的办法是去官网的 Releases / Timelines 查看每个大版本的维护截止时间;后面讲自动更新、平台兼容、安全修复时,版本策略都会回头影响你的决策。
四、本地 Node 与运行时 Node 不是一回事
一个很容易误解的点:你本地装的 Node.js 版本,和 Electron 应用运行时内部的 Node.js,不是同一个概念。课程让大家先确认本地 Node,是为了初始化项目、安装依赖、运行开发命令;但应用最终跑起来时,真正执行代码的是 Electron 自带的 Node.js 运行时。你可以用 process.versions 在应用里打印三个版本号:
console.log(process.versions.node) // Electron 内置 Node 版本
console.log(process.versions.chrome) // 内置 Chromium 版本
console.log(process.versions.electron) // Electron 自身版本这三个值和本机 node -v 往往并不一致。理解这个差异很关键:升级 Electron 会连带影响 Node 与 Chromium 的能力边界,所以“本地 Node 版本”绝不能直接等同于“应用运行时 Node 版本”;在引入原生模块(native modules)时,还必须让原生模块的 ABI 与 Electron 内置 Node 匹配,这是另一个容易踩坑的地方。
五、官网怎么读:Tutorial → Releases → API
面对 Electron 这种大型生态,最高效的阅读顺序不是一头扎进 API 词典,而是先看 Tutorial(懂整体路线)、再看 Releases / Timelines(看版本怎么维护)、最后在写具体功能时回到 API 查细节。课程重点点到的模块也很明确:主进程相关 API、渲染进程相关 API、调试与开发工具扩展、原生模块、自动更新。
这种“先主线后细节”的读法,本质上是在教你怎么读文档,而不只是文档里写了什么。它和后面的章节是对得上的:主进程 / 渲染进程 API 对应生命周期与窗口管理,调试扩展对应开发体验,自动更新对应发布链路。按这个顺序上手,遇到新版本变动时也更容易定位变更点,而不是被海量 API 淹没。
六、最小 Hello Electron 只有三步
课程带的第一个最小应用,逻辑极其克制,只有三步:写一个 createWindow()、在 app.whenReady() 之后调用它、在窗口里 loadFile("index.html")。它几乎就是后面所有 Electron 应用的起点——有一个应用实例 app、一个窗口 BrowserWindow、一个被加载的页面。这一步刻意“只做主进程里创建一个窗口”,为后面主进程 / 渲染进程的分工埋下伏笔。
这里还值得区分 loadFile 与 loadURL:前者加载本地文件(开发最小应用时最安全、最直观),后者加载远程地址(生产环境要谨慎,后面安全章节会展开)。此时还没有复杂通信和系统 API,目标只是先把一个 Electron 壳子跑起来——先拿到“能启动的窗口”,再谈更复杂的架构。
七、国内安装慢的本质与加速思路
Electron 安装慢是非常普遍的现象,根因是它不像普通 npm 包——安装时还会拉取 Electron 自身的二进制运行时。课程给了两类加速思路:一类是换安装源(如 cnpm),另一类是配置 Electron 的镜像地址(如设置 ELECTRON_MIRROR)。官方文档也保留了自定义 mirror / cache 的安装说明。
真正的本质不是“某淘宝源一定最快”,而是给 Electron 二进制下载找一条更适合当前网络环境的链路;不同网络环境下最优镜像不一定相同。所以建立“安装慢是正常现象”的预期,比死磕某个源更务实——一旦你接受这是 Electron 的固有特征,就不会在每次 npm install 卡住时误以为是自己环境配错了。
八、把 Hello Electron 落成可运行的最小工程
把前三步落成文件,最小工程由三部分组成:package.json 声明入口 main 与启动脚本 electron .;index.js 作为主进程入口,用 BrowserWindow 创建窗口并加载本地 HTML;index.html 是被渲染的页面。下面用 ESM / TypeScript 风格重写这个最小闭环,并补上 macOS 上常见的“点 Dock 重新激活窗口”逻辑:
import { app, BrowserWindow } from "electron"
import path from "node:path"
function createWindow() {
const win = new BrowserWindow({ width: 800, height: 600 })
win.loadFile(path.join(__dirname, "index.html"))
}
app.whenReady().then(() => {
createWindow()
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})package.json 里 main 决定 Electron 启动时先执行哪个入口脚本,scripts.start = "electron ." 表示以当前目录为应用根启动。到这里,桌面端篇章已经从“为什么选 Electron”正式推进到“把 Electron 跑起来”,后面的主进程生命周期、IPC、安全边界,全部建立在这个最小闭环之上。
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 为何 Electron 聚焦桌面端而非移动端 | 官网定位明确以 Web 技术做跨平台桌面应用 | 把它和 Tauri / Flutter 的路线区分开看 |
| 包体积为何明显大于纯 Web 应用 | 内置了 Chromium 与 Node.js 运行时 | 这是完整运行时的代价,属权衡而非缺陷 |
| 版本要不要永远追最新 | 大版本迭代快,但超支持窗口后无官方修复 | 优先用仍在支持窗口内且稳定的版本 |
| 本地 Node 18 但 Electron 内版本不同 | 运行时用的是 Electron 自带 Node.js | 用 process.versions 区分两者 |
| 官网信息太多先读哪 | 一头扎进 API 词典容易迷路 | 先 Tutorial,再 Releases,最后查 API |
| 安装为什么这么慢 | 不仅拉 npm 包,还下载 Electron 二进制 | 换源或配置 ELECTRON_MIRROR 镜像 |
| 为什么主进程里不直接写页面逻辑 | 主进程负责窗口与系统层,渲染交给 HTML | 先抓住“主进程创建窗口”这条最小主线 |
| 为何要补 activate 逻辑 | macOS 点 Dock 可能不重建窗口 | 在 app.on("activate") 里按需重建 |
| 为何 Electron 用 Web 技术而非原生 | 它选择复用前端生态而非重写原生 UI | 理解这是定位取舍,不是能力缺陷 |
| 首次跑通后下一步学什么 | 已拿到最小闭环,接下来是生命周期与 IPC | 顺着 05、06 继续深入主进程与调试 |