跳到主要内容
Electron 前端开发快速入门教程:从零搭建到打包部署 | 极客日志
JavaScript Node.js 大前端
Electron 前端开发快速入门教程:从零搭建到打包部署 Electron 是基于 Chromium 和 Node.js 的跨平台桌面应用框架。介绍从零搭建 Electron 工程,配置 main.js 与渲染进程通信(preload.js),实现本地文件读写及多系统兼容。对比 electron-builder 与 Electron Forge 打包方式,推荐使用 Forge 简化流程。涵盖环境准备、项目初始化、热更新配置及最终打包部署步骤。
神经兮兮 发布于 2026/4/5 更新于 2026/5/24 29 浏览Electron 前端开发快速入门教程
⚠️注意:
原视频打包时,使用 electron-builder 打包,访问 GitHub 可能需要网络环境配置。
本笔记使用 Electron Forge 进行打包,更友好。在 Electron 官网中也推荐使用这种方式 👉 Electron Forge Overview
一、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 官网地址
需要 node 和 npm,先检测是否安装。
node -v
npm -v
3.2 项目初始化
命令行创建
mkdir my-electron-app && cd my-electron-app
npm init
{
"name" : "my-electron-app" ,
"version" : "1.0.0" ,
"description" : "test Electron" ,
"main" : "main.js" ,
"author" : "Developer" ,
"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" : "Developer" ,
"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'" >
<meta http-equiv ="Content-Security-Policy" content ="default-src none" >
<meta http-equiv ="Content-Security-Policy" content ="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src self 'data:';" >
4.2.3 增加多系统的兼容代码 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 ()
})
})
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 打包,打包时要访问 github 需要网络环境配置 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" : "Developer" ,
"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 这个文件夹。然后用系统清理工具清理垃圾。然后重启即可。
其他 bug
软件有卡死的现象
还会自动重启
软件关闭后会自动重启
在输入框中输入内容,写入后可能会卡死,第二次可能无法输入,但可以读取。
启动时有点卡
六、总结
后面有的 bug 可能与 Electron Forge 配置有关。有时间试试,找个解决方案。
也有可能与 main.js 写法有关。
打包时删除 main.js 里的 win.openDevTools() //自动打开调试窗口 否则软件会自动打开调试窗口。
终于完成,虽然有 bug,但能运行起来了。后续找个更好的解决方案。
相关免费在线工具 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