跳到主要内容
Electron 一小时快速上手指南:前端桌面应用开发教程 | 极客日志
JavaScript Node.js 大前端
Electron 一小时快速上手指南:前端桌面应用开发教程 综述由AI生成 介绍 Electron 桌面应用开发快速入门。内容包括项目初始化、主进程配置、创建浏览器窗口、加载本地页面、处理内容安全策略(CSP)、实现跨平台兼容性、配置热更新以及使用 preload 脚本建立渲染进程与主进程的通信。最后演示了使用 Electron Forge 进行打包部署,解决了网络依赖问题并生成了可执行文件。
不知所云 发布于 2026/4/6 更新于 2026/5/24 25 浏览Electron 快速入门
注意 :
原视频打包使用 electron-builder,访问 GitHub 需要网络环境支持。
本笔记使用 Electron Forge 进行打包,无需访问 GitHub,更友好。Electron 官网也推荐使用这种方式。
一、Electron 是什么
简单的一句话,就是用 HTML+CSS+JS+Node.js+(Native API) 做兼容多个系统(Windows、Linux、Mac)的软件。
官网解释如下:
Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。嵌入 Chromium 和 Node.js 到二进制的 Electron 允许您保持一个 JavaScript 代码库并创建在 Windows 上运行的跨平台应用 macOS 和 Linux——不需要本地开发经验。
二、Electron 流程模型
三、Electron 搭建工程,若成功则输出 123
3.1 准备
参考 Electron 官网地址:Electron Quick Start
需要 node 和 npm,先检测是否安装。
node -v
npm -v
3.2 项目初始化
命令行创建:
mkdir my-electron-app && cd my-electron-app
npm init
或者手动快速创建。
package.json 文件示例:
{
"name" : "my-electron-app" ,
"version" :
"1.0.0"
,
"description"
:
"test Electron"
,
"main"
:
"main.js"
,
"author"
:
"Author Name"
,
"license"
:
"MIT"
}
entry point 应为 main.js。
author 与 description 可为任意值,但对于应用打包是必填项。
3.3 安装 Electron npm install --save-dev electron
// 或者
npm install electron -D
3.4 配置并启动 在 package.json 配置文件中的 scripts 字段下增加一条 start 命令:
{
"scripts" : {
"start" : "electron ."
}
}
{
"name" : "my-electron-app" ,
"version" : "1.0.0" ,
"main" : "main.js" ,
"scripts" : {
"start" : "electron ."
} ,
"author" : "bin9153" ,
"license" : "ISC" ,
"description" : "electron test" ,
"dependencies" : {
"electron" : "^31.2.0"
}
}
先创建 main.js,否则报错。
如果 main.js 里没写输出(或其他代码)则,启动了运行窗口也不容易看出变化。
四、开始制作程序
4.1 案例 1:做一个简易网页程序 const { app, BrowserWindow } = require ('electron' )
app.on ('ready' , () => {
const win = new BrowserWindow ({
width : 800 ,
height : 600 ,
autoHideMenuBar : true ,
alwaysOnTop : true ,
x : 0 ,
y : 0
})
win.loadURL ('https://example.com' )
})
4.2 案例 2:做一个本地程序(不是远程链接页面,是自己写的页面)
4.2.1 是本地程序,所以创建新的页面 新建 pages 目录,创建页面,这里就像写前端一样了。index.html, index.css。
<!DOCTYPE html >
<html lang ="en" >
<head >
<meta charset ="UTF-8" >
<title > 这里是 index 页面</title >
</head >
<body >
<h1 > 这里是 index 里的标题</h1 >
</body >
</html >
const { app, BrowserWindow } = require ('electron' )
app.on ('ready' , () => {
const win = new BrowserWindow ({
width : 800 ,
height : 600 ,
autoHideMenuBar : true ,
alwaysOnTop : true
})
win.loadFile ('./pages/index/index.html' )
})
4.2.2 解决内容安全策略 在 index.html 里加入如下代码,内容安全策略警告提示消失。
<meta http-equiv ="Content-Security-Policy" content ="default-src 'self'; script-src 'self'" >
4.2.3 增加多系统的兼容代码 兼容 mac(完善窗口行为)。
参考 Electron 文档:
在 main.js 里写入兼容各个系统平台的代码:
const { app, BrowserWindow } = require ('electron' )
function createWindow ( ) {
const win = new BrowserWindow ({
width : 800 ,
height : 600 ,
autoHideMenuBar : true ,
alwaysOnTop : true
})
win.loadFile ('./pages/index/index.html' )
}
app.on ('ready' , () => {
createWindow ()
app.on ('activate' , () => {
if (BrowserWindow .getAllWindows ().length === 0 ) createWindow ()
})
})
app.on ('window-all-closed' , () => {
if (process.platform !== 'darwin' ) app.quit ()
})
app.on ('ready' , () => {
})
app.whenReady ().then (() => {
})
4.2.4 配置自动重启,保存后自动热更新 {
"start" : "nodemon --exec electron ."
}
这样保存 main.js 里的内容,就自动热更新了。
但是更新 index.html 里的代码不能热更新,要加一个 nodemon.json,需要手动添加:
{
"ignore" : [ "node_modules" , "dist" ] ,
"restartable" : "r" ,
"watch" : [ "*.*" ] ,
"ext" : "html,js,css"
}
4.2.5 编写页面程序 (写一个应用程序,可以写入任意文字到 hello.txt 里) 每个页面程序通过渲染和主进程通信,主进程根据需求调用 Native API 来实现功能。
实际,每个页面和主程序通信时,需要建个桥梁来管理它们的通信,preload.js(自己创建),来管理实现通信。
在 main.js 中定义 preload.js 为桥梁:
const { app, BrowserWindow } = require ('electron' )
const path = require ('path' )
function createWindow ( ) {
const win = new BrowserWindow ({
width : 800 ,
height : 600 ,
autoHideMenuBar : true ,
alwaysOnTop : true ,
webPreferences : {
preload : path.resolve (__dirname, './preload.js' )
}
})
win.loadFile ('./pages/index/index.html' )
win.openDevTools ()
console .log ("main.js" )
}
app.on ('ready' , () => {
createWindow ()
app.on ('activate' , () => {
if (BrowserWindow .getAllWindows ().length === 0 ) createWindow ()
})
})
这是自己整理的,整理了前面 45 分钟,再这么整理下去,1000 字也不够用。
下面写代码不详细介绍了。会点前端的能懂一半多代码。
直接上代码。
const { app, BrowserWindow , ipcMain } = require ('electron' )
const path = require ('path' )
const fs = require ('fs' )
function writeFile (_, data ) {
fs.writeFileSync ('D:/hello.txt' , data)
}
function readFile ( ) {
const res = fs.readFileSync ("D:/hello.txt" ).toString ()
return res
}
function createWindow ( ) {
const win = new BrowserWindow ({
width : 800 ,
height : 600 ,
autoHideMenuBar : true ,
alwaysOnTop : true ,
webPreferences : {
preload : path.resolve (__dirname, './preload.js' )
}
})
ipcMain.on ('file-save' , writeFile)
ipcMain.handle ('file-read' , readFile)
win.loadFile ('./pages/index/index.html' )
win.openDevTools ()
console .log ("main.js" )
}
app.on ('ready' , () => {
createWindow ()
app.on ('activate' , () => {
if (BrowserWindow .getAllWindows ().length === 0 ) createWindow ()
})
})
const { contextBridge, ipcRenderer } = require ('electron' )
contextBridge.exposeInMainWorld ('myAPI' , {
version : process.version ,
saveFile : (data ) => {
ipcRenderer.send ('file-save' , data)
},
readFile ( ) {
return ipcRenderer.invoke ('file-read' )
}
})
const btn1 = document .getElementById ("btn1" )
const btn2 = document .getElementById ("btn2" )
const btn3 = document .getElementById ("btn3" )
const input = document .getElementById ("inp" )
btn1.onclick = () => {
alert (myAPI.version )
}
btn2.onclick = () => {
myAPI.saveFile (input.value )
}
btn3.onclick = async () => {
const res = await myAPI.readFile ()
alert (res)
}
<!DOCTYPE html >
<html lang ="en" >
<head >
<meta charset ="UTF-8" >
<meta http-equiv ="Content-Security-Policy" content ="default-src 'self'; script-src 'self'" >
<title > 这里是 index 页面</title >
</head >
<body >
<h1 > 欢迎学习 Electron 开发!!!</h1 >
<button id ="btn1" > 点我</button >
<hr />
<input type ="text" id ="inp" />
<button id ="btn2" > 向 D 盘写入 hello.txt</button >
<hr >
<button id ="btn3" > 读取 hello.txt 的内容</button >
<script type ="text/javascript" src ="./render.js" > </script >
</body >
</html >
备注 :
代码稍微有点不一样
目录结构也有变化,功能是一样的
五、打包
5.1 使用 electron-builder 打包 npm install electron-builder -D
在 package.json 中进行相关配置,具体配置如下:
备注:json 文件不支持注释,使用时请去掉所有注释。
{
"name" : "video-tools" ,
"version" : "1.0.0" ,
"main" : "main.js" ,
"scripts" : {
"start" : "electron ." ,
"build" : "electron-builder"
} ,
"build" : {
"appId" : "com.atguigu.video" ,
"win" : {
"icon" : "./logo.ico" ,
"target" : [ { "target" : "nsis" , "arch" : [ "x64" ] } ]
} ,
"nsis" : {
"oneClick" : false ,
"perMachine" : true ,
"allowToChangeInstallationDirectory" : true
}
} ,
"devDependencies" : {
"electron" : "^30.0.0" ,
"electron-builder" : "^24.13.3"
} ,
"author" : "Author" ,
"license" : "ISC" ,
"description" : "A video processing program based on Electron"
}
根据视频操作未能完成打包,这种方式在打包时访问 GitHub 多次尝试后,决定放弃。
5.2 使用 Electron Forge 进行打包
5.2.1 使用 3 条命令,完成打包。 npm install --save-dev @electron-forge/cli
npx electron-forge import
这时在 package.json 里会增加一些配置,不用管。
5.2.2 打包后的位置 打包后的文件,在根项目下的 out 文件夹里。
可运行程序在 my-electron-app\out\make\squirrel.windows\x64
5.2.3 看运行效果
5.2.4 出现的 bug
安装一次后再打开会报错。
直接删除软件,目录在 C:\Users\Administrator\AppData\Roaming 删除 my_electron_app 这个文件夹。然后用 360 安全卫士清理垃圾。然后重启即可。
其他 bug
软件有卡死的现象
还会自动重启
软件关闭后会自动重启
在输入框中输入内容,写入后可能会卡死,第二次可能无法输入,但可以读取。
启动时有点卡
六、总结
后面有的 bug 可能与 Electron Forge 配置有关。有时间试试,找个解决方案。
也有可能与 main.js 写法有关。
打包时删除 main.js 里的 win.openDevTools(),否则软件会自动打开调试窗口。
代码仓库位置:https://gitee.com/electron_9/my-electron-app (仅供参考)
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online