一小时快速上手Electron——上篇(Electron架构解析、核心进程实战、从零构建首个应用)
1. 开篇为什么你需要了解Electron如果你是一个前端开发者或者对Web技术比较熟悉那么你肯定有过这样的想法我写的这些网页能不能直接变成一个独立的、能安装在电脑上的软件呢比如你用Vue或React写了一个很棒的工具页面你想把它分享给朋友但朋友说“啊还要打开浏览器输入网址好麻烦”。这时候Electron就登场了。简单来说Electron能让你用你熟悉的HTML、CSS和JavaScript直接构建出Windows、macOS和Linux上的桌面应用程序。你每天用的Visual Studio Code、Slack、Discord甚至新版桌面版QQ它们的“身体”里都流淌着Electron的血液。我知道一听到“桌面应用”、“原生API”、“进程通信”这些词你可能觉得头大感觉又要学一套全新的、复杂的东西。别担心这正是我写这篇文章的目的。我当年第一次接触Electron时也被各种概念绕得晕头转向什么主进程、渲染进程感觉比写网页复杂多了。但后来我发现一旦你理解了它的核心架构上手速度其实快得惊人。今天我就用我这几年踩过坑、填过坑的经验带你在一小时内从“这是什么”到“嘿我的第一个桌面应用跑起来了”。我们不讲空泛的理论直接从它的“心脏”开始解剖然后手把手带你敲出第一个窗口。相信我跟着走完这一趟你不仅能看懂Electron应用是怎么跑起来的还能自己动手搭建一个基础框架。2. 剥开外壳Electron的“三明治”架构到底是什么很多教程一上来就说“Electron Chromium Node.js”这个说法对但不够完整容易让人产生误解。我更喜欢把它比喻成一个“三明治”或者“三层夹心蛋糕”。最上面一层是Chromium负责给你一个漂亮的、能渲染网页的窗口最下面一层是Node.js赋予你这个应用在用户电脑上“为所欲为”的能力比如读写文件、操作数据库而中间最关键的那层粘合剂就是Native API原生API。少了这一层你的应用就只是个披着本地软件外衣的浏览器标签页。让我用个更生活的例子来解释。假设你想开一家既能线上点单网页功能又能现场制作美食系统操作的“数字餐厅”。Chromium就是你餐厅的门面和厨房展示区顾客用户在这里通过精美的菜单HTML/CSS点餐看到食物制作过程JavaScript交互。但你的厨房系统后台需要接入水电燃气系统资源、采购食材读写本地文件这些Chromium自己搞不定。这时候Node.js就是你的后厨总管它有权限去调用这些基础设施。而Native API就是标准化的操作手册和接口它告诉Node.js在Windows系统里怎么开水阀在macOS里怎么开燃气你不用关心底层具体怎么拧阀门只需要调用“打开水源()”这个统一的命令就行。所以Electron的本质是让Chromium的渲染能力、Node.js的系统操作能力通过Native API这座桥梁无缝协作。你写的Vue/React组件最终会被Chromium渲染成窗口里的界面而当你需要保存一个用户设置文件到“我的文档”时你的代码会通过Electron提供的通道让Node.js去执行fs.writeFile。这种融合让你既能享受Web开发的快速和生态又能获得原生应用的能力和体验。理解了这个“三明治”模型后面所有的概念比如进程都是在这个模型上展开的。3. 核心运转模型主进程与渲染进程的“双簧戏”理解了架构我们得看看它是怎么跑起来的。这就是Electron的流程模型核心就是两个角色主进程Main Process和渲染进程Renderer Process。你可以把它想象成一场双簧表演。3.1 主进程后台的“总导演”主进程通常就是你项目根目录下的那个main.js文件名字可以改但约定俗成叫这个。它是整个Electron应用的入口和大脑只有一个。它的运行环境是一个纯净的Node.js环境。这意味着什么意味着在这个main.js文件里你可以毫无顾忌地使用require引入模块用fs读写文件用path处理路径所有Node.js的能力你都可以直接调用。但是正因为它是纯粹的Node环境所以它没有浏览器里的那些对象。你在主进程里写document.getElementById或者window.alert是会报错的它不认识这些因为它根本没有DOM和BOM的概念。主进程的核心职责是“管理”它用app模块管理应用的生命周期比如什么时候启动、什么时候退出用BrowserWindow模块创建和管理一个个应用窗口。它就像是剧组的导演待在后台不直接面对观众用户但指挥着一切。3.2 渲染进程前台的“演员”每一个由BrowserWindow创建出来的窗口背后都对应着一个渲染进程。你打开一个Electron应用弹出一个设置窗口这个新窗口通常就对应一个新的渲染进程。渲染进程的环境就和我们日常写前端时一模一样了一个Chromium渲染引擎提供的浏览器环境。在这里你可以操作DOM可以使用alert、console.log可以跑Vue、React框架可以引入Axios发请求和你开发一个网页没有任何区别。但是这个“浏览器”是被限制的。出于安全考虑默认情况下渲染进程不能直接访问Node.js的API你不能在渲染进程的JavaScript里直接写require(‘fs’)去删用户文件。这就像舞台上的演员虽然在前台表演但不能随便跑到后台去动导演的设备和剧本。这种设计非常重要它防止了来自网络的恶意代码比如你加载了一个第三方网页对用户系统造成破坏。3.3 联系与区别他们如何“对暗号”那么前台演员渲染进程需要后台导演主进程帮忙办点事比如保存文件怎么办这就需要进程间通信IPC Inter-Process Communication。Electron提供了一套完善的IPC机制让主进程和渲染进程可以安全地互相传递消息和数据。举个例子在渲染进程一个Vue组件里用户点击“保存”按钮需要把数据存成一个本地.json文件。渲染进程自己没权限它就通过IPC给主进程发个消息“嘿导演帮我把这段数据存到D:/data/config.json里”。主进程收到消息后调用Node.js的fs模块执行写入操作完成后再通过IPC回个消息“办妥了”。渲染进程收到回信就可以在界面上给用户显示“保存成功”的提示。它们的区别总结一下就是环境主进程是Node.js环境渲染进程是浏览器环境。数量主进程有且仅有一个渲染进程可以有多个每个窗口一个或多个窗口共享一个。权限主进程拥有全部Node.js和系统原生API调用权限渲染进程默认只有Web API权限需要特殊配置或通过IPC才能间接使用Node.js能力。职责主进程管理应用和窗口生命周期渲染进程负责界面展示和用户交互。搞懂了这场“双簧戏”你就掌握了Electron应用运行的核心脉络。接下来我们不再空谈直接动手让理论落地。4. 从零到一构建你的第一个Electron应用“Hello World”理论说再多不如亲手敲一遍。这个部分我们抛开一切脚手架和复杂工具就用最原始的方式从零创建一个Electron应用。你会清晰地看到每一个文件是如何产生的每一条命令是什么作用。4.1 环境准备打好地基首先你需要一个基础环境Node.js。这是Electron的基石。我强烈建议你使用nvmNode Version Manager来管理Node.js版本这能让你在不同项目间切换版本时游刃有余。去nvm的GitHub仓库下载安装包安装完成后在终端里执行一条命令就能装上最新的长期支持版nvm install 18 nvm use 18安装好后打开你的终端命令行输入node -v和npm -v如果能显示出版本号比如v18.20.0和10.7.0那就说明环境OK了。另外为了后续安装包速度更快建议把npm的镜像源切换到国内源npm config set registry https://registry.npmmirror.com/4.2 项目初始化创建你的工作区接下来找个你喜欢的地方新建一个文件夹名字随意比如my-first-electron-app。然后用你的代码编辑器比如VSCode打开这个文件夹并打开集成终端。我们将在这里执行所有命令。第一步初始化一个npm项目这会生成一个package.json文件来记录你的项目信息和依赖npm init -y那个-y参数的意思是“对所有问题都回答yes”省去你一路回车的麻烦。执行完后你会看到文件夹里多了一个package.json文件。4.3 引入核心安装Electron现在我们来安装今天的主角——Electron。注意我们把它安装为开发依赖devDependency因为最终打包时Electron的运行时会被包含进去你的源代码并不直接依赖它。npm install electron --save-dev这条命令会从镜像源下载Electron包。由于Electron本身体积不小可能需要等待一会儿。安装成功后你的package.json文件里devDependencies部分会多出一项electron: ^版本号。4.4 编写主进程脚本让应用“活”起来还记得我们说的“总导演”吗现在我们来创建它。在项目根目录下新建一个文件命名为main.js。这个文件就是我们的主进程入口。打开main.js让我们写下第一行代码// main.js const { app, BrowserWindow } require(electron);这行代码从electron模块中引入了两个最重要的类app和BrowserWindow。app代表整个应用程序BrowserWindow则用来创建和控制浏览器窗口。接下来我们需要监听应用“准备就绪”的事件。只有当app就绪后我们才能开始创建窗口。app.whenReady().then(() { console.log(应用准备就绪开始创建窗口...); // 在这里创建窗口 });app.whenReady()返回一个Promise我们可以在.then()回调里执行初始化操作。现在让我们在回调里创建一个宽800像素、高600像素的窗口app.whenReady().then(() { console.log(应用准备就绪开始创建窗口...); const mainWindow new BrowserWindow({ width: 800, height: 600, // 可选隐藏默认的菜单栏让窗口更简洁 autoHideMenuBar: true }); // 加载内容到窗口 // 我们先尝试加载一个简单的网页 mainWindow.loadURL(https://www.electronjs.org); });我们创建了一个BrowserWindow实例并把它赋值给变量mainWindow以便后续引用。然后我们调用loadURL方法让这个窗口加载Electron的官网。这就像在浏览器里打开了一个新标签页一样。最后我们需要处理一下所有窗口都关闭后的情况。在macOS上应用通常不会直接退出我们需要显式地监听窗口关闭事件。// 监听所有窗口关闭的事件非macOS平台 app.on(window-all-closed, () { if (process.platform ! darwin) { app.quit(); } }); // 在macOS上当点击dock图标且没有其他窗口打开时重新创建一个窗口 app.on(activate, () { if (BrowserWindow.getAllWindows().length 0) { createWindow(); // 这里需要把创建窗口的逻辑封装成函数我们稍后优化 } });4.5 配置与运行点亮你的第一个窗口主进程脚本写好了我们还需要告诉Electron从哪里启动。打开package.json文件找到main字段把它改成我们主进程文件的路径{ name: my-first-electron-app, version: 1.0.0, main: main.js, scripts: { start: electron . }, devDependencies: { electron: ^29.0.0 } }同时我们在scripts里添加一条start: electron .的命令。这样我们就可以用npm start来启动应用了。现在激动人心的时刻到了在终端里运行npm start几秒钟后你应该会看到一个桌面窗口弹出来里面显示着Electron的官方网站你的第一个Electron应用成功运行了虽然它现在只是加载了一个网页但你已经完成了一个完整的Electron应用从环境搭建、初始化、编码到运行的全过程。这个窗口就是一个完整的、独立的桌面应用程序窗口而不是浏览器标签页。你可以尝试拖动它、最大化、最小化感受一下它和普通软件窗口的别无二致。4.6 更进一步从加载网页到加载本地界面加载外部网站只是演示我们真正想做的是运行自己的前端代码。让我们来改进一下。首先在项目根目录下创建一个index.html文件!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title我的第一个Electron应用/title style body { margin: 0; padding: 40px; font-family: sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; } h1 { font-size: 3em; margin-bottom: 20px; } button { padding: 15px 30px; font-size: 1.2em; border: none; border-radius: 50px; background: white; color: #667eea; cursor: pointer; font-weight: bold; transition: transform 0.2s; } button:hover { transform: scale(1.05); } /style /head body h1 你好Electron/h1 p这是我的第一个桌面应用窗口。/p button idclickMe点我试试/button script document.getElementById(clickMe).addEventListener(click, () { alert(你好来自渲染进程的问候); }); /script /body /html然后修改main.js中的loadURL那一行从加载远程URL改为加载本地文件。这里需要注意路径问题。我们使用Node.js的path模块和__dirname变量来构建绝对路径这样更可靠。// 在文件顶部引入 path 模块 const path require(path); // ... 在 whenReady 的回调函数内修改 loadURL 部分 mainWindow.loadFile(path.join(__dirname, index.html));__dirname代表当前main.js文件所在的目录path.join能帮我们跨平台地拼接出index.html的完整路径。保存所有文件再次运行npm start。现在窗口里显示的就是我们自定义的、带有渐变背景和交互按钮的HTML页面了点击按钮会弹出原生的警告框。至此你已经完成了一个具备本地界面和基础交互的完整Electron应用雏形。5. 深入窗口控制让你的应用更像“原生软件”现在应用能跑了但看起来还有点“简陋”。我们来看看如何通过配置BrowserWindow让它行为更符合一个桌面应用的习惯。5.1 常用窗口配置详解创建BrowserWindow时传入的那个配置对象功能非常强大。我们来试试几个常用的const mainWindow new BrowserWindow({ width: 1000, height: 700, // 不显示默认的菜单栏File, Edit, View... autoHideMenuBar: true, // 窗口图标需要准备一个 .ico 或 .png 文件 icon: path.join(__dirname, assets, icon.png), // 窗口标题 title: 我的专属应用, // 窗口背景色在加载页面内容前显示 backgroundColor: #2e2e2e, // 是否允许改变窗口大小 resizable: true, // 窗口是否可以最小化、最大化、关闭 minimizable: true, maximizable: true, closable: true, // 窗口是否始终显示在最前面 alwaysOnTop: false, // 是否显示窗口边框和标题栏设置为false可创建无边框窗口 frame: true, // 窗口是否透明需要结合 frame: false 使用 transparent: false, // 窗口是否在创建后立即显示 show: true, // 网页功能的偏好设置 webPreferences: { // 这是一个非常重要的安全设置我们下篇会详细讲 nodeIntegration: false, // 预加载脚本的路径进程通信的关键 preload: path.join(__dirname, preload.js) } });你可以像搭积木一样组合这些配置来打造你想要的窗口样式和行为。比如设置frame: false和transparent: true你就能做出那种不规则形状、毛玻璃效果的“现代化”应用界面。5.2 管理窗口生命周期窗口创建了我们还需要妥善管理它。比如你可能会想阻止用户直接关闭窗口而是先弹出一个确认框。// 监听窗口关闭事件在关闭之前触发 mainWindow.on(close, (event) { // 阻止默认的关闭行为 event.preventDefault(); // 这里可以显示一个自定义的对话框询问用户 // 为了示例我们简单使用控制台日志 console.log(用户试图关闭窗口可以在这里做保存或确认操作。); // 如果确认要关闭可以调用 mainWindow.destroy(); });在实际项目中你可能会在这里检查文档是否需要保存或者询问用户“确定要退出吗”。掌握了这些你就从一个“能跑通”的初学者向“做得精致”的实践者迈进了一步。窗口是用户与你的应用交互的主要界面把它打磨好用户体验会提升很多。

相关新闻

【TSmaster】从零到一:用TSmaster打造专属上位机监控面板

【TSmaster】从零到一:用TSmaster打造专属上位机监控面板

1. 为什么你需要一个专属的上位机监控面板? 如果你正在做汽车电子、工业控制或者机器人相关的开发,我猜你对下面这个场景一定不陌生:电脑上开着好几个软件窗口,一个看CAN报文原始数据,一个看DBC解析后的信号值&#xf…

2026/7/4 16:41:11 阅读更多 →
iOS 通过 NEHotspotHelper 实现智能 WiFi 网络自动连接

iOS 通过 NEHotspotHelper 实现智能 WiFi 网络自动连接

1. 为什么你需要了解 NEHotspotHelper? 想象一下这个场景:你走进一家常去的咖啡馆,手机自动连上了店里的WiFi,甚至在你还没掏出手机看菜单时,一个友好的登录页面就弹了出来。或者,当你回到家门口&#xff0…

2026/5/17 12:29:22 阅读更多 →
Git团队协作实战:高效解决同一分支下的代码冲突

Git团队协作实战:高效解决同一分支下的代码冲突

1. 从“单打独斗”到“并肩作战”:为什么代码冲突是团队协作的常态 很多刚接触团队开发的朋友,可能觉得Git用起来挺顺手的,自己提交、拉取、推送都没问题。但一旦和几个同事一起在同一个分支(比如master或develop)上干…

2026/7/5 12:19:41 阅读更多 →

最新新闻

哈夫曼编码是一种基于字符出现频率的变长前缀编码方法,它通过构建最优二叉树(哈夫曼树)为每个符号分配唯一且无歧义的二进制码,**不丢失任何原始信息*

哈夫曼编码是一种基于字符出现频率的变长前缀编码方法,它通过构建最优二叉树(哈夫曼树)为每个符号分配唯一且无歧义的二进制码,**不丢失任何原始信息*

哈夫曼编码属于 B. 无损压缩 ✅ 原因:哈夫曼编码是一种基于字符出现频率的变长前缀编码方法,它通过构建最优二叉树(哈夫曼树)为每个符号分配唯一且无歧义的二进制码,不丢失任何原始信息,解码后可完全恢复原…

2026/7/6 14:37:30 阅读更多 →
手把手教你学 Simulink — 氢燃料电池 Boost DC‑DC 的阳极过压保护(OVP)仿真

手把手教你学 Simulink — 氢燃料电池 Boost DC‑DC 的阳极过压保护(OVP)仿真

目录 手把手教你学 Simulink — 氢燃料电池 Boost DC‑DC 的阳极过压保护(OVP)仿真 一、总体建模结构(先给“地图”) 二、燃料电池模型(Thevenin 极化 LUT) 2.1 极化曲线(示例,…

2026/7/6 14:37:30 阅读更多 →
无障碍设施开放公告增量采集,实战教学!

无障碍设施开放公告增量采集,实战教学!

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐⭐⭐☆☆(进阶级) 🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。 全文目录: 🌟…

2026/7/6 14:33:27 阅读更多 →
视频号下载神器:3分钟搞定全网热门资源批量下载的终极指南

视频号下载神器:3分钟搞定全网热门资源批量下载的终极指南

视频号下载神器:3分钟搞定全网热门资源批量下载的终极指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 你是否…

2026/7/6 14:31:26 阅读更多 →
怎样判断一个技术人的认知在你之上:不是会说大词,而是这7个信号

怎样判断一个技术人的认知在你之上:不是会说大词,而是这7个信号

文章目录前言一、第一个信号:他先管理身体,而不是先喊意志力二、第二个信号:他遇到问题先找信息差,而不是急着表态三、第三个信号:他不跟你硬吵,因为他看到的是地基四、第四个信号:他情绪稳定&a…

2026/7/6 14:29:23 阅读更多 →
具身智能的定义、特征与原理解析(3)

具身智能的定义、特征与原理解析(3)

前沿技术介绍:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,属于“物理AI” 领域的一种全新技术形态,完成了从“虚拟世界”到“…

2026/7/6 14:29:23 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻