快速入门
约 6132 字大约 20 分钟
2025-10-28
1.基本要求
1.1.沙盒环境
Electron 是一个使用 HTML、CSS、JS 构建桌面应用程序的框架。在嵌入 Chromium 和 Node.js 到二进制的 Electron 中,允许您保持一个 JavaScript 代码代码库并创建跨平台桌面应用 Windows、MacOS、Linux,且不需要本地开发的经验。
建议您从 教程 开始,该教程将指导您完成开发 Electron 应用程序并将其分发给用户的过程。示例 和 API 文档也是浏览和发现新事物的好地方。
对于小白来说,想要快速体验,可以考虑使用 Electron Fiddle。这是由 Electron 开发并由其维护者支持的沙盒程序(不过我一般直接推荐您使用后面的开发环境工具)。强烈建议将其作为一个学习工具来安装,以便在开发过程中对 Electron 的 API 进行实验或对特性进行原型化。
Fiddle 已经完美的集成到帮助文档之中。当您浏览官方教程中的例子,你会发现有个 「Open In Electron Fiddle」 按钮在代码示例中。如果你已经安装了 Fiddle 时,「Open In Electron Fiddle」 按钮会打开一个 fiddle.electronjs.org 链接并加载示例。
这里以 Ubuntu 22.04 环境作为例子,访问官方网站 获取 .deb 包来安装。
sudo apt install ./electron-fiddle_0.37.2_amd64.deb然后您需要了解下面的知识,就可以开始动工。
1.2.开发环境
开发环境就直接使用 Electron Forge,沙盒环境和开发环境的区别在于:
| 对比项 | Electron Fiddle | Electron Forge |
|---|---|---|
| 定位 | 实验 / 学习工具 | 项目脚手架与构建系统 |
| 面向人群 | 学习者、API 研究者 | 开发者、生产环境应用 |
| 运行方式 | 图形界面(GUI) | 命令行(CLI) |
| 项目保存 | 可导出临时项目或 Gist | 标准 npm 项目结构 |
| 是否可打包发布 | ❌ 否 | ✅ 可以 |
| 是否能管理依赖 | ❌ 否(内置固定 Electron 版本) | ✅ 可以(npm/yarn) |
不过要安装 Electron Forge 就需要先安装 Node.js,这个比较简单,去官网搜索就可以,直接安装最新的就可以(这里认为您已经安装过了,直接安装其他核心的东西)。
重要
补充:虽然您需要在开发环境安装 Node.js 才能编写 Electron 项目,但是 Electron 不使用您系统的 Node.js 环境来运行它的代码。相反地,它使用它内置的 Node.js 运行时。 这意味着您的终端用户不需要 Node.js 环境也可以运行您的应用。
其实 Electron Forge 就是一个打包工具而已。
2.创建应用
ljp@limou3434:~/temp$ mkdir my-electron-app && cd my-electron-app
ljp@limou3434:~/temp/my-electron-app$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (my-electron-app)
version: (1.0.0)
description: 一个测试 electron 的项目
entry point: (index.js)
test command: echo "hello"
git repository:
keywords:
author: limou3434
license: (ISC)
type: (commonjs)
About to write to /home/ljp/temp/my-electron-app/package.json:
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "一个测试 electron 的项目",
"main": "index.js",
"scripts": {
"test": "echo \"hello\""
},
"author": "limou3434",
"license": "ISC",
"type": "commonjs"
}
Is this OK? (yes) yes
ljp@limou3434:~/temp/my-electron-app$ ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm install --save-dev electron
npm warn deprecated boolean@3.2.0: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
added 70 packages, and audited 71 packages in 4s
17 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities在初始化并且安装完 Electron 之后,您的 package.json 应该长下面这样。文件夹中会出现一个 node_modules 文件夹,其中包含了 Electron 可执行文件。还有一个 package-lock.json 文件,指定了各个依赖的确切版本。
ljp@limou3434:~/temp/my-electron-app$ cat package.json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "一个测试 electron 的项目",
"license": "ISC",
"author": "limou3434",
"type": "commonjs",
"main": "index.js",
"scripts": {
"test": "echo \"hello\""
},
"devDependencies": {
"electron": "^39.0.0"
}
}既然是 JS 项目,那么自然可以使用 Webstorm 工具来作为 IDE 工具(个人推荐)。
您在 package.json 中指定的 main 文件是 Electron 应用的入口。 这个文件控制 主进程 (main process),它运行在 Node.js 环境里,负责控制您应用的生命周期、显示原生界面、执行特殊操作并管理 渲染器进程 (renderer processes),稍后会详细介绍。
在继续编写您的 Electron 应用之前,您将使用一个小小的脚本来确保主进程入口点已经配置正确。 在根目录的 index.js 文件中写一行代码:
console.log('Hello from Electron 👋')重要
补充:因为 Electron 的主进程就是一个 Node.js 运行时,所以你可以直接用 electron 命令运行任意的 Node.js 代码(甚至还能把它当成 REPL 来用)。
要执行这个脚本,需要在 package.json 的 scripts 字段中添加一个 start 命令,内容为 electron . 。这个命令会告诉 Electron 在当前目录下寻找主脚本,并以开发模式运行它。
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "一个测试 electron 的项目",
"main": "index.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "limou3434",
"license": "MIT",
"devDependencies": {
"electron": "^38.4.0"
}
}/home/ljp/.nvm/versions/node/v22.18.0/bin/yarn run start
yarn run v1.22.22
$ electron .
Hello from Electron 👋重要
补充:Electron 28 起,Electron 支持 ECMAScript 模块(即使用 import 加载模块)。您可以在我们的 ESM 指南 中找到有关 Electron 中 ESM 状态以及如何在我们的应用程序中使用它们的更多信息。
如果需要快速创建一个桌面程序,则需要稍微了解一些进程模型的知识:Electron 继承了来自 Chromium 的多进程架构,这使得此框架在架构上非常相似于一个现代的网页浏览器(实际上哪怕是一个简单的页面也很类似)。为什么不是一个单一的进程?网页浏览器是个极其复杂的应用程序。除了显示网页内容的主要能力之外,他们还有许多次要的职责,例如:管理众多窗口(标签页)和加载第三方扩展。
在早期,浏览器通常使用单个进程来处理所有这些功能。虽然这种模式意味着您打开每个标签页的开销较少,但也同时意味着一个网站的崩溃或无响应会影响到整个浏览器。为了解决这个问题,Chrome 团队决定让每个标签页在自己的进程中渲染,从而限制了一个网页上的有误或恶意代码可能导致的对整个应用程序造成的伤害。然后用单个浏览器进程控制这些标签页进程,以及整个应用程序的生命周期。下方来自 Chrome 漫画的图表可视化了此模型。

Electron 应用程序的结构非常相似。作为应用开发者,您将控制两种类型的进程(这类似于 Chrome 的浏览器和渲染器进程):
- 主进程:每个
Electron应用都有一个单一的主进程,作为应用程序的入口点。主进程在Node.js环境中运行,这意味着它具有require模块和使用所有Node.js API的能力。- 窗口管理:主进程的首要目的是使用
BrowserWindow模块创建和管理应用程序窗口。 - 生命周期:主进程通过
Electron的app模块,也控制着你应用程序的生命周期。该模块提供了一整套的事件和方法,可以让您用来添加自定义的应用程序行为(例如:以编程方式退出您的应用程序、修改应用dock,或显示一个关于面板)。 - 原生接口:为了使
Electron的功能不仅仅限于对网页内容的封装,主进程也添加了自定义的API来与用户的作业系统进行交互。Electron有着多种控制原生桌面功能的模块,例如菜单、对话框以及托盘图标。
- 窗口管理:主进程的首要目的是使用
- 渲染器进程:每个
Electron应用都会为每个打开的BrowserWindow(与每个网页嵌入)生成一个单独的渲染器进程。洽如其名,渲染器负责渲染网页内容。所以实际上,运行于渲染器进程中的代码是须遵照网页标准的(至少就目前使用的Chromium而言是如此)。因此,一个浏览器窗口中的所有的用户界面和应用功能,都应与您在网页开发上使用相同的工具和规范来进行攥写。
因此我们需要一个标准的浏览器页面,然后在 index.js 中编写主进程和渲染器进程的相关代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
</body>
</html>const { app, BrowserWindow } = require('electron')
// app: 这个模块控制着您应用程序的事件生命周期
// BrowserWindow: 这个模块创建和管理 app 的窗口
// createWindow() 函数将新的 BrowserWindow 窗口实例中, 并且将您的页面加载到实例中
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html') // 实际上只需要使用 win.loadURL('https://...') 就可以快速把网页程序运行为桌面程序(这就是魅力所在)
}
// whenReady 是异步方法, 表示 "等 Electron 初始化完成后再执行后续代码"
app.whenReady().then(() => {
createWindow()
})
// 关闭所有窗口时退出应用 (Windows & Linux)
app.on('window-all-closed', () => {
// 平台 process.platform 值 说明
// Windows 'win32' 32/64 位都一样, Node 统一用 'win32'
// macOS 'darwin' 来自 Darwin 内核
// Linux 'linux' 大部分 Linux 发行版
// FreeBSD 'freebsd' BSD 系统
// OpenBSD 'openbsd' BSD 系统
// SunOS 'sunos' Solaris 系统
// AIX 'aix' IBM AIX 系统
// Android 'android' Node 支持 Android 时返回
// Node.js 早期还有 'cygwin' 不常用, Windows Cygwin 环境
if (process.platform !== 'darwin') {
console.log('关闭所有窗口时退出应用')
app.quit()
}
})
// 如果没有窗口打开则打开一个窗口 (macOS)
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
console.log('如果没有窗口打开则打开一个窗口')
createWindow()
}
})重要
补充:您可能注意到了 app 和 BrowserWindow 两个模块名的大小写差异。Electron 遵循 JavaScript 传统约定,以帕斯卡命名法(PascalCase)命名可实例化的类 (如 BrowserWindow, Tray 和 Notification),以驼峰命名法 (camelCase) 命名不可实例化的函数、变量等(如 app, ipcRenderer, webContents) 。
重要
补充:Electron 的许多核心模块都是 Node.js 的事件触发器,遵循 Node.js 的异步事件驱动架构,app 模块就是其中一个。
重要
补充:通常我们使用触发器的 .on 函数来监听 Node.js 事件。
+ app.on('ready', () => {
- app.whenReady().then(() => {
createWindow()
})但是 Electron 暴露了 app.whenReady() 方法,作为其 ready 事件的专用监听器,这样可以避免直接监听 .on 事件带来的一些问题,参见 electron/electron#21972。
重要
补充:如果您希望使用 VS Code 调试您的程序,您需要让 VS Code 监听主进程和渲染器进程。下面为您提供了一个简单的配置文件,请在根目录新建一个 .vscode 文件夹,然后在其中新建一个 launch.json 配置文件并填写如下内容。
{
"version": "0.2.0",
"compounds": [
{
"name": "Main + renderer",
"configurations": ["Main", "Renderer"],
"stopAll": true
}
],
"configurations": [
{
"name": "Renderer",
"port": 9222,
"request": "attach",
"type": "chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Main",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": [".", "--remote-debugging-port=9222"],
"outputCapture": "std",
"console": "integratedTerminal"
}
]
}保存后,当您选择侧边栏的“运行和调试”,将会出现一个 "Main + renderer" 选项。然后您便可设置断点,并跟踪主进程和渲染器进程中的所有变量。
上文中我们在 launch.json 所做的其实是创建三个配置项:
Main用来运行主程序,并且暴露出9222端口用于远程调试(--remote-debugging-port=9222)。 我们将把调试器绑定到那个端口来调试renderer。因为主进程是Node.js进程,类型被设置为node。Renderer用来调试渲染器进程。因为后者是由主进程创建的,我们要把它“绑定”到主进程上"request": "attach",而不是创建一个新的。渲染器是web进程,因此要选择chrome调试器。Main + renderer是一个 复合任务,可以同时执行上述任务。
由于我们要将进程绑定到 Renderer 任务,您应用中的前几行代码可能会被跳过,因为调试器 Debugger 在执行代码之前没有足够的时间进行连接。在开发环境中,您可以通过刷新页面或者使用 setTimeout 延迟运行代码,来避开这个问题。
如果您希望深挖调试步骤,可以查看以下指南:
3.预载脚本
Electron 的主进程是一个拥有着完全操作系统访问权限的 Node.js 环境。在 Electron 模块的基础上,你还可以访问 Node.js 内建模块,以及通过 npm 安装的任何包。另一方面,出于安全原因,渲染进程默认跑在网页页面上,而并非 Node.js 里。为了将 Electron 的不同类型的进程桥接在一起,我们需要使用被称为 预加载 的特殊脚本。
预加载(preload)脚本包含了那些执行于渲染器进程中,且先于网页内容开始加载的代码。这些脚本虽运行于渲染器的环境中,却因能访问 Node.js API 而拥有了更多的权限。其实就是在网页加载前,安全地把 Node.js 或主进程的功能“桥接”给网页用。否则网页代码上的恶意脚本就能删文件、关电脑,非常危险。
重要
补充:不过其实就算是预载脚本,在以前也是拥有完全的 Node.js 权限的。在 Electron 20 之前,preload 脚本确实是一个完整的 Node.js 环境,可以:
- 访问文件系统(
fs) - 执行系统命令(
child_process) - 甚至直接读写系统敏感目录
但——它的设计初衷并不是让你在里面干这些事,而是用来:“在 main(主进程)和 renderer(渲染进程)之间安全地通信”。
也就是说:
- 主进程 可以访问所有系统资源。
- 渲染进程(网页) 不能直接访问系统资源,否则就不安全。
- preload 脚本 本来是一个中间层,负责通过
contextBridge.exposeInMainWorld把安全的接口暴露给网页。
所以 preload 的“权限大”是个设计副作用,不是特性。Electron 后来(从 v20 起)意识到很多开发者误用 preload 去干系统操作,所以就收紧了,默认沙盒化,只保留安全的 polyfill require。
| 版本 | preload 环境 | Node.js 权限 | require 行为 |
|---|---|---|---|
Electron 19 及以前 | 非沙盒 | 完整 | 可全加载 Node API |
Electron 20+(默认) | 沙盒(sandbox: false 取消) | 受限 | 只能加载 Polyfilled API |
预加载脚本运行在渲染进程之前,而其实就主要提供了两个作用:
- 一个作用是渲染进程和主系统交互
- 一个作用是渲染进程和主进程交互
3.1.增强渲染
BrowserWindow 的预加载脚本运行在具有 HTML DOM、Node.js、Electron API 的 有限子集 访问权限的环境中。与 Chrome 扩展的 内容脚本, Content Script 类似,预加载脚本在渲染器加载网页之前注入(这样渲染器就可以使用预加载脚本中定义的变量和函数)。为了向您的渲染器添加需要特权访问的功能,您可以通过 contextBridge api 定义全局对象。为了演示这一概念,你将会创建一个将应用中的 Chrome、Node、Electron 版本号暴露至渲染器的预加载脚本。
我们在根目录下新建一个 preload.js 文件,在 preload 里用 contextBridge 定义“白名单 API”,这里 Preload 的 require 看起来和 Node.js 的 require 一样,但只能加载 官方允许的安全模块(也就是所谓的“有限子集”)。我们使用 contextBridge 来定义允许使用的函数和变量。
# package.json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "一个测试 electron 的项目",
"main": "index.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "limou3434",
"license": "MIT",
"devDependencies": {
"electron": "^38.4.0"
}
}// preload.js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron
// 除函数之外, 我们也可以暴露变量, 不过暂时先这样, 后面可以在前端中使用 versions.chrome() 来执行方法
})// index.js
const { app, BrowserWindow } = require('electron')
const path = require('node:path')
// app: 这个模块控制着您应用程序的事件生命周期
// BrowserWindow: 这个模块创建和管理 app 的窗口
// createWindow() 函数将新的 BrowserWindow 窗口实例中, 并且将您的页面加载到实例中
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// __dirname 字符串指向当前正在执行的脚本的路径(在本例中, 它指向你的项目的根文件夹)
// path.join API 将多个路径联结在一起, 创建一个跨平台的路径字符串
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html') // 实际上只需要使用 win.loadURL('https://...') 就可以快速把网页程序运行为桌面程序(这就是魅力所在)
}
// whenReady 是异步方法, 表示 "等 Electron 初始化完成后再执行后续代码"
app.whenReady().then(() => {
createWindow()
})
// 关闭所有窗口时退出应用 (Windows & Linux)
app.on('window-all-closed', () => {
// 平台 process.platform 值 说明
// Windows 'win32' 32/64 位都一样, Node 统一用 'win32'
// macOS 'darwin' 来自 Darwin 内核
// Linux 'linux' 大部分 Linux 发行版
// FreeBSD 'freebsd' BSD 系统
// OpenBSD 'openbsd' BSD 系统
// SunOS 'sunos' Solaris 系统
// AIX 'aix' IBM AIX 系统
// Android 'android' Node 支持 Android 时返回
// Node.js 早期还有 'cygwin' 不常用, Windows Cygwin 环境
if (process.platform !== 'darwin') {
console.log('关闭所有窗口时退出应用')
app.quit()
}
})
// 如果没有窗口打开则打开一个窗口 (macOS)
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
console.log('如果没有窗口打开则打开一个窗口')
createWindow()
}
})// renderer.js
const information = document.getElementById('info')
information.innerText = `本应用正在使用 Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), 和 Electron (v${versions.electron()})`<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>来自 Electron 渲染器的问好!</title>
</head>
<body>
<h1>来自 Electron 渲染器的问好!</h1>
<p>👋</p>
<p id="info"></p>
</body>
<script src="./renderer.js"></script>
</html>
3.2.进程通信
不过我们前面只是允许渲染程序调用 Electron 的运行环境中的 Node,有时候在主进程中写的程序也需要和渲染进程进通信,所以既可以增强渲染,也可以进程通信。
我们之前提到,Electron 的主进程和渲染进程有着清楚的分工并且不可互换。这代表着无论是从渲染进程直接访问 Node.js 接口,亦或者是从主进程访问 HTML 文档对象模型 DOM,都是不可能的。
解决这一问题的方法是使用进程间通信 IPC。可以使用 Electron 的 ipcMain 模块和 ipcRenderer 模块来进行进程间通信。为了从您的网页向主进程发送消息,你可以使用 ipcMain.handle 设置一个主进程处理程序(handler),然后在预处理脚本中暴露一个被称为 ipcRenderer.invoke 的函数来触发该处理程序(handler)。
我们将向渲染器添加一个叫做 ping() 的全局函数来演示这一点。这个函数将返回一个从主进程翻山越岭而来的字符串。
# package.json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "一个测试 electron 的项目",
"main": "index.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "limou3434",
"license": "MIT",
"devDependencies": {
"electron": "^39.0.0"
}
}// preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
ping: () => ipcRenderer.invoke('ping') // IPC, 这里的 'ping' 参数是 IPC 通信的通道名称
// 除函数之外, 我们也可以暴露变量, 不过暂时先这样, 后面可以在前端中使用 versions.chrome() 来执行方法
})// index.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
// app: 这个模块控制着您应用程序的事件生命周期
// BrowserWindow: 这个模块创建和管理 app 的窗口
// createWindow() 函数将新的 BrowserWindow 窗口实例中, 并且将您的页面加载到实例中
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// __dirname 字符串指向当前正在执行的脚本的路径(在本例中, 它指向你的项目的根文件夹)
// path.join API 将多个路径联结在一起, 创建一个跨平台的路径字符串
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html') // 实际上只需要使用 win.loadURL('https://...') 就可以快速把网页程序运行为桌面程序(这就是魅力所在)
}
// whenReady 是异步方法, 表示 "等 Electron 初始化完成后再执行后续代码"
app.whenReady().then(() => {
ipcMain.handle('ping', () => 'pong') // IPC 捕捉到 'ping' 消息就响应 'pong'
createWindow()
})
// 关闭所有窗口时退出应用 (Windows & Linux)
app.on('window-all-closed', () => {
// 平台 process.platform 值 说明
// Windows 'win32' 32/64 位都一样, Node 统一用 'win32'
// macOS 'darwin' 来自 Darwin 内核
// Linux 'linux' 大部分 Linux 发行版
// FreeBSD 'freebsd' BSD 系统
// OpenBSD 'openbsd' BSD 系统
// SunOS 'sunos' Solaris 系统
// AIX 'aix' IBM AIX 系统
// Android 'android' Node 支持 Android 时返回
// Node.js 早期还有 'cygwin' 不常用, Windows Cygwin 环境
if (process.platform !== 'darwin') {
console.log('关闭所有窗口时退出应用')
app.quit()
}
})
// 如果没有窗口打开则打开一个窗口 (macOS)
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
console.log('如果没有窗口打开则打开一个窗口')
createWindow()
}
})// renderer.js
const information = document.getElementById('info')
information.innerText = `本应用正在使用 Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), 和 Electron (v${versions.electron()})`
// IPC, 相当于把声明放在预载文件中, 定义在主进程中, 调用在渲染进程中
const func = async () => {
const response = await window.versions.ping() // 这里会把 IPC 结果返回
console.log(response) // 打印 'pong'
}
func()<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>来自 Electron 渲染器的问好!</title>
</head>
<body>
<h1>来自 Electron 渲染器的问好!</h1>
<p>👋</p>
<p id="info"></p>
</body>
<script src="./renderer.js"></script>
</html>
4.打包应用
先安装我们前面说的 Electron Forge。
ljp@limou3434:~/temp/my-electron-app$ ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm install --save-dev @electron-forge/cli
npm warn gitignore-fallback No .npmignore file found, using .gitignore for file exclusion. Consider creating a .npmignore file to explicitly control published files.
npm warn skipping integrity check for git dependency ssh://git@github.com/electron/node-gyp.git
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs
npm warn deprecated lodash.get@4.4.2: This package is deprecated. Use the optional chaining (?.) operator instead.
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@8.1.0: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@8.1.0: Glob versions prior to v9 are no longer supported
npm warn gitignore-fallback No .npmignore file found, using .gitignore for file exclusion. Consider creating a .npmignore file to explicitly control published files.
added 461 packages, and audited 532 packages in 54s
86 packages are looking for funding
run `npm fund` for details
5 low severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
ljp@limou3434:~/temp/my-electron-app$
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npx electron-forge import
✔ Checking your system
✔ Locating importable project
✔ Processing configuration and dependencies
✔ Resolving package manager: npm
✔ Configuring Yarn (if applicable)
✔ Installing dependencies
✔ Copying base template Forge configuration
✔ Fixing .gitignore
✔ Finalizing import
› We have attempted to convert your app to be in a format that Electron Forge understands.
Thanks for using Electron Forge!转换脚本完成后,Forge 会将一些脚本添加到您的 package.json 文件中。您还应该注意到您的 package.json 现在安装了更多的包在 devDependencies 下,以及一个导出配置的新 forge.config.js 文件目的。您应该会在预填充的配置中看到多个 makers(生成可分发应用程序包的包),每个目标平台一个。这样这成功导入到项目中了。
要创建可分发文件,请使用项目中的 make 脚本,该脚本最终运行了 electron-forge make 命令。
ljp@limou3434:~/temp/my-electron-app$ ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ sudo apt install rpm && npm run make重要
补充:在本地发布可能会很痛苦,特别是因为您只能基于您的主机操作系统创建可分发文件(即您无法从 macOS 发布 Windows 的 .exe 文件)。
更新日志
403d4-修改 Github 工作流的配置,以方便未来支持前后端拓展于