跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端

Electron 前端跨平台桌面应用开发快速入门教程

Electron 是基于 Chromium 和 Node.js 构建跨平台桌面应用的框架。内容涵盖环境准备、项目初始化、主进程与渲染进程通信机制、本地文件读写及打包发布流程。通过配置 preload.js 桥接通信,解决 CSP 安全策略问题,并适配 Windows、macOS 及 Linux 系统。最后演示使用 Electron Forge 完成打包部署及常见运行问题的排查。

1qazxsw2发布于 2026/4/8更新于 2026/5/2618 浏览
Electron 前端跨平台桌面应用开发快速入门教程

⚠️注意:

  1. 使用 electron-builder 打包时,访问 github 可能需要网络代理。
  2. 本笔记使用 Electron Forge 进行打包,无需访问 github,更友好。在 Electron 官网中也推荐使用这种方式 👉 Electron

一、Electron 是什么

简单的一句话,就是用 html+css+js+nodejs+(Native Api) 做兼容多个系统(Windows、Linux、Mac)的软件。

官网解释如下:
Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。嵌入 Chromium 和 Node.js 到二进制的 Electron 允许您保持一个 JavaScript 代码库并创建在 Windows 上运行的跨平台应用 macOS 和 Linux——不需要本地开发经验。

Electron 架构示意图

Electron 运行原理图

二、Electron 流程模型

Electron 流程模型图

三、Electron 搭建工程,若成功则输出 123

3.1 准备

可参考 Electron 官网地址
需要 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",
  "license": "MIT"
}

有几条规则需要遵循:

  • entry point 应为 main.js.
  • author 与 description 可为任意值,但对于应用打包是必填项。

package.json 配置说明

3.3 安装 Electron

npm install --save-dev electron
// 或者 npm install electron -D

3.4 配置并启动

在 package.json 配置文件中的 scripts 字段下增加一条 start 命令:

{
  "scripts": {
    "start": "electron ."
  }
}

这一步,完整的 package.json

{
  "name": "my-electron-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "author": "Author",
  "license": "ISC",
  "description": "electron test",
  "dependencies": {
    "electron": "^31.2.0"
  }
}

代码解析:

package 代码解析

创建 main.js。

main.js 文件

在 main.js 里写入

console.log(123)

控制台输出

再运行!

npm start

注意:

  1. 先创建 main.js,否则报错
  2. 如果 main.js 里没写输出(或其他代码)则,启动了运行窗口也不容易看出变化

启动输出 123

成功输出 123,工程搭建完成。

四、开始制作程序

4.1 案例 1:做一个简易网页程序

点击可以查看,browser-window 配置项的开发文档
在 main.js 里写入

const { app, BrowserWindow } = require('electron')
app.on('ready', () => {
  // 当 app 准备好后,执行 createWindow 创建窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    autoHideMenuBar: true,
    alwaysOnTop: true,
    x: 0,
    y: 0
  })
  // 加载远程页面
  win.loadFile('./pages/index.html')
})

运行

npm start

制作一个远程界面

成功显示页面。

4.2 案例 2:做一个本地程序(不是远程链接页面,是自己写的页面)

4.2.1 是本地程序,所以创建新的页面

新建 pages 目录,创建页面,这里就像写前端一样了。index.html, index.css

目录结构

index.html 里

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>这里是 index 页面</title>
</head>
<body>
  <h1>这里是 index 里的标题</h1>
</body>
</html>

main.js 里引入页面

const { app, BrowserWindow } = require('electron')
app.on('ready', () => {
  // 当 app 准备好后,执行 createWindow 创建窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    autoHideMenuBar: true,
    alwaysOnTop: true
  })
  // 引入页面
  win.loadFile('./pages/index.html')
})

运行

npm start
4.2.2 解决内容安全策略

有安全提示

安全提示

在 index.html 里加入,如下代码,内容安全策略警告提示消失。

<!-- electron 提供的配置 -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<!-- electron 提供的配置 2 引入 js 后也会报错 -->
<meta http-equiv="Content-Security-Policy" content="default-src none">
<!-- 视频教程里的配置 会报错 -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self';style-src 'self''unsafe-inline';img-src self'data:'">
<!-- 我自己写的组合的配置更全 加了一个 script 的限制,有事儿后期再改,刚试了会报错,可能哪里没写对,先记录在这里 -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self';style-src 'self''unsafe-inline';img-src self'data:'">

安全策略代码详解

关于 CSP 的详细说明:MDN 内容安全策略详解、Electron 安全策略规范

4.2.3 增加多系统的兼容代码

兼容 mac(完善窗口行为)
electron 文档:
关闭所有窗口时退出应用 (Windows & Linux)
如果没有窗口打开则打开一个窗口 (macOS)
在 main.js 里写入兼容各个系统平台的代码

const { app, BrowserWindow } = require('electron')
function createWindow() {
  // 当 app 准备好后,执行 createWindow 创建窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    autoHideMenuBar: true,
    alwaysOnTop: true
  })
  win.loadFile('./pages/index.html')
}
app.on('ready', () => {
  createWindow()
  // 兼容核心代码 1
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
// 兼容核心代码 2
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

代码解析

代码解析

下面两句代码相等

app.on('ready', () => {
  // 写核心代码
})
// 或者
app.whenReady().then(() => {
  // 写核心代码
})
4.2.4 配置自动重启,保存后自动热更新
npm i nodemon -D

package.json 里重写 start

{
  "start": "nodemon --exec electron ."
}

重写 start

这样保存 main.js 里的内容,就自动热更新了。
但是更新 index.html 里的代码不能热更新,要加一个 nodemon.json,需要手动添加

{
  "ignore": ["node_modules", "dist"],
  "restartable": "r",
  "watch": ["*.*"],
  "ext": "html,js,css"
}

增加 nodemon.json,

增加 nodemon 文件和内容

重启生效

npm start
4.2.5 编写页面程序 (写一个应用程序,可以写入任意文字到 hello.txt 里)

页面程序要写在页面里,那它和主进程的关系如图

Electron 流程模型图

每个页面程序通过渲染和主进程通信,主进程根据需求调用 Native Api 来实现功能。

实际,每个页面和主程序通信时,需要建个桥梁来管理它们的通信,preload.js(自己创建),来管理实现通信。

通信机制图

创建 preload.js 定义桥梁 js

创建 preloadjs

在 main.js 中定义 preload.js 为桥梁

在 main.js 里定义桥梁

main.js 代码:

const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow() {
  // 当 app 准备好后,执行 createWindow 创建窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    autoHideMenuBar: true,
    alwaysOnTop: true,
    webPreferences: {
      // 在 main.js 中定义 preload.js 为桥梁
      preload: path.resolve(__dirname, './preload.js')
    }
  })
  // 引入页面
  win.loadFile('./pages/index.html')
  win.openDevTools()
  // 自动打开调试窗口
  console.log("main.js")
}
app.on('ready', () => {
  createWindow()
  // 兼容核心代码 1
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

创建渲染 js

创建渲染 js

定义渲染 js

定义渲染 js

下面直接上代码。

main.js 里的代码

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() {
  // 当 app 准备好后,执行 createWindow 创建窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    autoHideMenuBar: true,
    alwaysOnTop: true,
    webPreferences: {
      // 在 main.js 中定义 preload.js 为桥梁
      preload: path.resolve(__dirname, './preload.js')
    }
  })
  ipcMain.on('file-save', writeFile)
  ipcMain.handle('file-read', readFile)
  // 引入页面
  win.loadFile('./pages/index.html')
  win.openDevTools()
  // 自动打开调试窗口
  console.log("main.js")
}
app.on('ready', () => {
  createWindow()
  // 兼容核心代码 1
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

preload.js 里的代码

const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
  version: process.version,
  saveFile: (data) => {
    ipcRenderer.send('file-save', data)
  },
  readFile() {
    return ipcRenderer.invoke('file-read')
  }
})

render.js 里的代码

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)
}

html 里的代码

<!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>

目录结构

目录结构

备注:

  1. 代码稍微有点不一样
  2. 目录结构也有变化,功能是一样的

五、打包

5.1 使用 electron-builder 打包,打包时要访问 github 需要网络代理

  1. 安装 electron-builder:
npm install electron-builder -D
  1. 在 package.json 中进行相关配置,具体配置如下:

备注:json 文件不支持注释,使用时请去掉所有注释。

打包配置图

package.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 进行打包(使用这种方式打包的)

Electron 中文网也推荐使用这种方式。
Electron Forge 是从建项目开始配置的,因为项目已经写完了,所以从第五步开始。
Electron Forge 从第五步开始的文档

5.2.1 使用 3 条命令,完成打包。
  1. 运行第 1 条命令
npm install --save-dev @electron-forge/cli
  1. 运行第 2 条命令
npx electron-forge import

这时在 package.json 里会增加一些配置。

在 package 里增加配置

不用管。

  1. 直接运行第 3 条命令
npm run make

打包完成。

5.2.2 打包后的位置,在根项目下的 out 文件里

打包后的文件,在根项目下的 out 文件夹里

打包后的文件

可运行程序在 my-electron-app\out\make\squirrel.windows\x64

可运行程序

5.2.3 看运行效果,终于完成了。

完成运行效果

5.2.4 出现的 bug
  1. 安装一次后再打开会报错,

再次安装报错

  1. 直接删除软件,目录在 C:\Users\Administrator\AppData\Roaming 删除 my_electron_app 这个文件夹。然后用 360 安全卫士清理垃圾。然后重启即可。

其他 bug

  1. 软件有卡死的现象
  2. 还会自动重启
  3. 软件关闭后会自动重启
  4. 在输入框中输入内容,写入后可能会卡死,第二次可能无法输入,但可以读取。
  5. 启动时有点卡

六、总结

  1. 后面有的 bug 可能与 Electron Forge 配置有关。有时间试试,找个解决方案。
  2. 也有可能与 main.js 写法有关。
  3. 打包时删除 main.js 里的 win.openDevTools() // 自动打开调试窗口,否则软件会自动打开调试窗口。
  4. 代码仓库位置 https://gitee.com/electron_9/my-electron-app

终于完成,虽然有 bug,但能运行起来了。后续找个更好的解决方案。

目录

  1. 一、Electron 是什么
  2. 二、Electron 流程模型
  3. 三、Electron 搭建工程,若成功则输出 123
  4. 3.1 准备
  5. 3.2 项目初始化
  6. 3.3 安装 Electron
  7. 3.4 配置并启动
  8. 四、开始制作程序
  9. 4.1 案例 1:做一个简易网页程序
  10. 4.2 案例 2:做一个本地程序(不是远程链接页面,是自己写的页面)
  11. 4.2.1 是本地程序,所以创建新的页面
  12. 4.2.2 解决内容安全策略
  13. 4.2.3 增加多系统的兼容代码
  14. 4.2.4 配置自动重启,保存后自动热更新
  15. 4.2.5 编写页面程序 (写一个应用程序,可以写入任意文字到 hello.txt 里)
  16. 五、打包
  17. 5.1 使用 electron-builder 打包,打包时要访问 github 需要网络代理
  18. 5.2 使用 Electron Forge 进行打包(使用这种方式打包的)
  19. 5.2.1 使用 3 条命令,完成打包。
  20. 5.2.2 打包后的位置,在根项目下的 out 文件里
  21. 5.2.3 看运行效果,终于完成了。
  22. 5.2.4 出现的 bug
  23. 六、总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 为 OpenClaw 构建双层记忆系统:QMD + Mem0 混合架构
  • GitHub 开源项目精选:AI 安全工具 Shannon 及热门项目汇总
  • Java 房屋租赁系统的设计与实现
  • 城市交通监控视频解析:GLM-4.6V-Flash-WEB 辅助违章事件识别
  • 基于链表实现队列的初始化、入队、出队及销毁操作
  • 基于 SpringBoot 和 PostGIS 的应急运输事件影响分析 - 1.31 侧翻事故案例
  • OpenClaw 在 Mac 上本地化部署及接入飞书教程
  • ArduPilot RemoteID Transmitter 实现无人机远程识别合规方案
  • 毕业就业信息管理系统:SpringBoot 后端+Vue 前端+MySQL 实现
  • 深度优先搜索与回溯法:全排列及子集问题的决策树与剪枝优化
  • 第二届人工智能、虚拟现实与交互设计国际学术会议(AIVRID 2026)
  • FLUX.1 镜像部署指南:内置中文界面与场景优化
  • 本地 AI 电话机器人:通过 UDP 传输手机通话声音的 Python 脚本
  • Go 语言连接 Kingbase 数据库实战:Gokb 驱动配置与使用指南
  • 随机森林(Random Forest)原理、流程详解与 Python 代码演示
  • AI 产品经理全流程工作指南:从需求定义到模型验收
  • 使用 ONNX 加载头部姿态评估模型并集成到 LLM Agent
  • Java 剪辑接单报价比价系统技术架构与源码解析
  • C++ 基础:RAII、智能指针与项目构建
  • 基于大型语言模型的智能 Agent:发展历程、架构与 Langchain 实现

相关免费在线工具

  • 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