精通 electron 快速开始
1. Electron 简介
Electron 是一个开源框架,允许开发者使用 Web 技术(如 JavaScript、HTML 和 CSS)来构建跨平台的桌面应用。
Electron 官网地址 https://www.electronjs.org/zh/
以下是关于 Electron 的简要介绍:
1.1 背景与起源
Electron 最初是由 GitHub 公司为其 Atom 编辑器项目开发的,但很快它成为了一个独立的框架,吸引了大量的开发者和公司。Electron 第一次公开发布是在 2013 年,当时的名称是 "Atom Shell",后来在 2015 年被重命名为 Electron。
1.2 主要特点
跨平台: 使用 Electron,你可以为 Windows、macOS 和 Linux 创建应用程序,而只需编写一次代码。
Web 技术: Electron 允许开发者使用他们已经熟悉的 Web 技术,如 HTML, CSS 和 JavaScript,来构建应用程序。
Chromium 集成: Electron 应用将 Chromium(一个开源的 Web 浏览器项目,也是 Google Chrome 的基础)包含在内,这意味着你可以使用最新的 Web API 和功能。
Node.js 集成: Electron 应用程序在其主进程和渲染进程中都集成了 Node.js,允许开发者使用 npm 包和 Node.js API。
原生 API 访问: Electron 提供了一系列的 API,允许开发者访问操作系统的底层功能,如文件系统、菜单、通知等。
1.3 一些知名的 Electron 应用
多个流行和大型的应用程序都是使用 Electron 构建的,包括但不限于:
- 抖音学浪
- 抖音直播伴侣
- pc qq
- 百度翻译
- 百度文库
- Visual Studio Code(由 Microsoft 开发的代码编辑器)
- Atom(一款流行的代码编辑器)
- Slack(团队沟通应用程序)
- Microsoft Teams(团队沟通和协作工具)
- Discord(针对游戏玩家的沟通平台)
- Trello Desktop(项目管理工具)
1.4 总结
Electron 提供了一个强大且灵活的方式来构建跨平台的桌面应用程序,使得 Web 开发者无需深入学习各种平台的原生开发技术就可以构建应用。这使得许多 Web 开发者和团队可以更快速地进入桌面应用领域。
2. 环境准备
2.1 安装 Node.js 和 npm
Electron 的核心依赖于 Node.js,因此首先需要安装 Node.js 和 npm(Node.js 的包管理器)。
下载 Node.js:
- 访问 Node.js 官方网站 https://nodejs.org/
- 根据你的操作系统选择合适的版本进行下载。建议下载 LTS(长期支持)版本,因为它更加稳定。
安装:
- 双击下载的安装程序,并按照提示进行安装。
验证安装:
- 打开终端或命令提示符。
- 输入
node -v
和npm -v
来确保两者都已正确安装。
bashnode -v npm -v
2.2 Electron 的安装
安装 Electron 非常简单,只需要使用 npm 命令。
创建一个新的项目文件夹:
bashmkdir my-electron-app cd my-electron-app
初始化 npm 项目:
bashnpm init
这将启动一个交互式会话来创建一个
package.json
文件。安装 Electron:
bashnpm install electron --save-dev
这将 Electron 安装为项目的开发依赖。
2.3 快速验证 Electron 安装
创建主文件:
在项目根目录中,创建一个名为
main.js
的文件,然后添加以下内容:javascriptconst { app, BrowserWindow } = require("electron"); function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); win.loadFile("index.html"); } app.on("ready", createWindow);
创建 HTML 文件:
在同一目录下,创建一个名为
index.html
的文件,并添加基本的 HTML 内容,例如:html<!DOCTYPE html> <html> <head> <title>My Electron App</title> </head> <body> <h1>Hello, Electron!</h1> </body> </html>
运行 Electron 应用:
修改
package.json
文件,将start
脚本更改为以下内容:json"scripts": { "start": "electron main.js" }
然后,运行以下命令启动 Electron 应用:
bashnpm start
这将启动 Electron,并你应该能看到一个显示 "Hello, Electron!" 的窗口。
通过以上步骤,你已经成功地设置了 Electron 的开发环境,并验证了它的安装。
3. Electron 基础
3.1 主进程和渲染进程
在 Electron 中,每个应用有一个主进程和一个或多个渲染进程。
主进程:
- 负责运行
package.json
的main
脚本,并执行应用的整个生命周期。 - 控制所有的 Web 页面和与它们的交互。
- 只有在主进程中才能调用某些 Electron 的原生 API。
- 一个 Electron 应用始终有一个主进程。
- 负责运行
渲染进程:
- 每个 Electron 的
BrowserWindow
在其自己的渲染进程中运行 Web 页面。 - 负责页面的渲染,即页面上的用户界面。
- 一个 Electron 应用可以有多个渲染进程。
- 与主进程相对独立,但二者之间可以通过 IPC(进程间通讯)进行通信。
- 每个 Electron 的
3.2 Electron 的主要模块
Electron 提供了一系列的模块来帮助开发者创建桌面应用。以下是其中的一些关键模块:
app:
- 控制应用的事件生命周期。
- 提供了应用关闭、准备完毕等事件。
BrowserWindow:
- 创建和管理应用窗口。
- 允许加载和渲染 Web 内容。
Menu 和 MenuItem:
- 为应用创建原生菜单。
ipcMain 和 ipcRenderer:
- 允许主进程和渲染进程之间的通信。
shell:
- 提供了与操作系统的 shell 交互的相关功能。
dialog:
- 提供了原生的对话框,如打开文件、保存文件等。
3.3 Electron 应用的生命周期
Electron 的 app
模块提供了与应用生命周期事件相关的方法和事件。
app 的 'ready' 事件:
- 当 Electron 完成初始化时触发。
- 此时通常会创建应用窗口。
app 的 'window-all-closed' 事件:
- 当所有窗口都被关闭时触发。
- 通常在这个事件中结束应用,除非在 macOS 中,其中通常会保持应用在 dock 中运行,直到用户显式地退出应用。
app 的 'activate' 事件 (macOS only):
- 当用户点击了应用的 dock 图标并且没有其他窗口打开时触发。
- 通常在这个事件中重新创建一个应用窗口。
这些基础知识为你提供了创建 Electron 应用的基本框架。了解这些基础后,你可以更深入地探索 Electron 的 API 并开始构建更复杂的应用。
4. 创建第一个 Electron 应用
4.1 初始化项目
创建项目文件夹:
bashmkdir my-first-electron-app cd my-first-electron-app
初始化 npm 项目:
bashnpm init -y
这将为你的项目创建一个默认的
package.json
文件。安装 Electron:
bashnpm install electron --save-dev
4.2 主文件与渲染文件
创建主文件 (
main.js
):在项目根目录中,创建一个名为
main.js
的文件。这是应用的入口点,负责创建窗口和管理应用的生命周期。javascriptconst { app, BrowserWindow } = require("electron"); let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); mainWindow.loadFile("index.html"); } app.on("ready", createWindow);
创建渲染文件 (
index.html
):在项目根目录下创建一个名为
index.html
的文件,用于展示应用的内容:html<!DOCTYPE html> <html> <head> <title>My First Electron App</title> </head> <body> <h1>Welcome to Electron!</h1> </body> </html>
4.3 Electron 应用窗口管理
在 Electron 中,可以通过 BrowserWindow
类创建和管理窗口。上面我们已经简单地创建了一个窗口。要进行更高级的窗口管理,如隐藏、最大化、最小化、关闭窗口等,你可以使用相应的 API 方法。
例如,关闭一个窗口:
mainWindow.close();
或者最小化窗口:
mainWindow.minimize();
你还可以添加事件监听,如当窗口关闭时:
mainWindow.on("closed", () => {
mainWindow = null;
});
4.4 运行和调试
设置启动脚本:
修改
package.json
中的scripts
部分,添加启动脚本:json"scripts": { "start": "electron main.js" }
运行应用:
在终端或命令提示符中,输入以下命令:
bashnpm start
此命令将启动 Electron,并显示你创建的窗口。
调试:
Electron 使用的 Chromium 引擎内置了 DevTools,你可以直接在 Electron 应用中使用这些开发者工具进行调试。
在
main.js
中,添加以下代码,使 DevTools 在应用启动时自动打开:javascriptmainWindow.webContents.openDevTools();
现在你已经成功创建了一个基本的 Electron 应用,并了解了如何进行简单的调试。随着对 Electron 的深入学习,你可以开始添加更多的功能和交互,创建复杂的桌面应用程序。
5. 与原生功能交互
Electron 允许你与计算机的原生功能进行交互,这也是其作为桌面应用开发框架的优势之一。
5.1 文件系统交互
Electron 应用可以直接使用 Node.js 的 fs
模块来操作文件系统。
示例:读取文件内容
const fs = require("fs");
fs.readFile("/path/to/file.txt", "utf-8", (err, data) => {
if (err) throw err;
console.log(data);
});
5.2 原生对话框
Electron 提供了 dialog
模块来显示原生的系统对话框,例如打开文件、保存文件、警告等。
示例:显示一个“打开文件”对话框
const { dialog } = require("electron");
const filePaths = dialog.showOpenDialogSync({
title: "Select a file",
properties: ["openFile"],
});
console.log(filePaths);
5.3 通知
Electron 提供了一个 Notification
API 来显示桌面通知。
示例:显示一个通知
const { Notification } = require("electron");
const notification = {
title: "Electron Notification",
body: "Hello from Electron!",
};
new Notification(notification).show();
5.4 菜单和上下文菜单
Electron 的 Menu
和 MenuItem
模块允许你创建原生的应用菜单和上下文菜单。
示例:创建一个应用菜单
const { Menu, BrowserWindow } = require("electron");
const menuTemplate = [
{
label: "File",
submenu: [
{
label: "Open",
click: () => {
// 执行“打开”逻辑
},
},
{
label: "Save",
click: () => {
// 执行“保存”逻辑
},
},
{ type: "separator" },
{ role: "quit" },
],
},
// ... 更多菜单项
];
const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu);
示例:创建一个上下文菜单
const { Menu, BrowserWindow } = require("electron");
const contextMenuTemplate = [
{
label: "Copy",
role: "copy",
},
{
label: "Paste",
role: "paste",
},
// ... 更多菜单项
];
const contextMenu = Menu.buildFromTemplate(contextMenuTemplate);
const win = new BrowserWindow();
win.webContents.on("context-menu", (event, params) => {
contextMenu.popup(win);
});
上面的示例展示了 Electron 如何与计算机的原生功能进行交互,使你可以创建与传统桌面应用一样具有丰富功能的 Electron 应用。
6. 网络操作和远程通讯
在 Electron 中,由于其基于 Node.js 和 Chromium,你可以使用各种 Web 和 Node.js 技术来进行网络操作和远程通讯。
6.1 使用 Axios 进行 HTTP 请求
Axios 是一个基于 Promise 的 HTTP 客户端,适用于浏览器和 Node.js,可以方便地进行 HTTP 请求。
安装:
npm install axios
示例:使用 Axios 发起 GET 请求
const axios = require("axios");
axios
.get("https://api.example.com/data")
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error("Error fetching data:", error);
});
6.2 与远程服务器交互
在 Electron 中,你可以使用各种技术与远程服务器进行交互,不仅仅是 HTTP 请求。
WebSockets:
使用 ws 或其他类似的库,你可以创建 WebSocket 连接,实现双向通信。
示例:
javascriptconst WebSocket = require("ws"); const ws = new WebSocket("ws://example.com/socket"); ws.on("open", () => { ws.send("Hello Server!"); }); ws.on("message", (data) => { console.log(`Received: ${data}`); });
IPC (Inter-Process Communication):
在 Electron 中,主进程和渲染进程之间可以使用 IPC 进行通讯。虽然它主要用于应用内部的通讯,但你可以结合 IPC 和其他技术(例如 WebSockets 或 HTTP)使渲染进程与远程服务器通信,然后将数据传递给主进程。
示例:从渲染进程发送数据给主进程
javascript// 在渲染进程 const { ipcRenderer } = require("electron"); ipcRenderer.send("send-data", { data: "Hello from Renderer" }); // 在主进程 const { ipcMain } = require("electron"); ipcMain.on("send-data", (event, arg) => { console.log(arg.data); // 输出 "Hello from Renderer" });
通过结合这些技术,Electron 开发者可以构建与远程服务器进行实时交互的复杂应用,无论是通过常规的 HTTP 请求,还是通过 WebSockets、gRPC 等更高级的通信机制。
7. 性能和安全性
Electron 允许开发者快速创建跨平台的桌面应用,但为了确保应用的响应速度和用户数据的安全性,需要特别关注性能和安全性。
7.1 性能优化建议
减少包大小:
- 使用工具如 webpack 来打包和优化代码。
- 剔除不必要的依赖和模块。
使用
lazy-loading
:- 只有当需要时才加载某些模块或资源。
优化渲染进程:
- 避免长时间的同步操作。
- 使用
requestAnimationFrame
对动画和持续的 UI 更新进行优化。
内存管理:
- 定期查看和检测内存使用情况。
- 使用工具如 Chrome DevTools 进行内存分析。
7.2 Electron 安全建议
限制 Node.js 功能:
- 在渲染进程中尽量禁用
nodeIntegration
,并使用preload
脚本来公开所需的功能。
- 在渲染进程中尽量禁用
禁用远程模块:
- 设置
enableRemoteModule
为false
,以阻止渲染进程访问 Electron APIs。
- 设置
验证和清理加载的内容:
- 只加载和执行来自可信来源的代码和内容。
- 不要执行未经验证的远程代码。
使用上下文隔离:
- 设置
contextIsolation
为true
,以确保渲染进程中的 Electron 和 Node.js 功能与页面内容完全隔离。
- 设置
7.3 CSP (内容安全策略) 的实施
内容安全策略 (CSP) 是一个额外的安全层,它可以帮助检测和缓解某些类型的攻击,如跨站脚本 (XSS) 和数据注入攻击。
设置 CSP 元标签:
在应用的 HTML 头部添加以下元标签:
html<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
这将限制脚本只能从同一个来源加载,并禁止内联脚本。
扩展和定制 CSP:
- 根据需要扩展 CSP,例如允许加载来自特定域的图像或样式。
- 对于更复杂的策略,可能需要结合多个 CSP 指令。
调试 CSP:
- 如果应用中的某些内容由于 CSP 而不加载或运行,浏览器控制台将显示相关的错误消息。
- 读取并根据这些错误消息调整 CSP。
在实施上述建议时,重要的是进行持续的审查和测试,以确保应用的性能和安全性满足预期。
8. 打包与分发
当你完成了 Electron 应用的开发,下一步是将它打包并分发给用户。这一章节将指导你如何有效地打包、分发和更新 Electron 应用。
8.1 使用 electron-builder
electron-builder 是一个完整的解决方案,用于打包和发布 Electron 应用。
安装:
npm install electron-builder --save-dev
配置: 在 package.json
中添加配置部分。这里是一个基本示例:
{
"build": {
"appId": "com.example.myapp",
"productName": "MyApp",
"directories": {
"output": "build"
},
"files": ["dist/**/*", "node_modules/**/*", "index.html", "main.js"],
"mac": {
"category": "public.app-category.utilities"
},
"win": {
"target": "nsis"
}
}
}
打包:
npm run electron-builder -- --mac --win
8.2 跨平台打包策略
目标平台: 确定你希望支持的平台(如 Windows、macOS、Linux)。
图标和资源: 为每个平台准备相应的图标和其他资源。
原生模块: 如果使用了原生 Node.js 模块,确保它们能够在所有目标平台上正确编译。
测试: 在每个目标平台上测试应用以确保其功能和性能。
8.3 自动更新
Electron 的 autoUpdater
模块允许你在应用中实现自动更新功能。与此同时,electron-builder
提供了易于使用的更新解决方案。
配置: 在 package.json
中的 build
部分配置更新服务器的 URL:
{
"build": {
...
"publish": {
"provider": "github",
"repo": "your-repo",
"owner": "your-username",
"private": false
}
}
}
实现自动更新: 在主进程的代码中:
const { autoUpdater } = require("electron-updater");
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on("update-available", () => {
// 提示用户更新可用
});
autoUpdater.on("update-downloaded", () => {
// 提示用户重新启动应用以完成更新
});
发布新版本: 当你发布应用的新版本时:
- 更新
package.json
中的版本号。 - 运行
electron-builder
来创建新的发布资产。 - 在 GitHub 或其他托管服务上发布新版本,并附加
electron-builder
生成的资产。
这样,当用户的应用下次启动时,它会自动检查、下载并提示用户安装新版本。
总之,正确地打包、分发和更新 Electron 应用是提供一个顺畅用户体验的关键部分,因此值得花时间和精力来确保这一过程的顺利进行。