Skip to content

精通 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 主要特点

  1. 跨平台: 使用 Electron,你可以为 Windows、macOS 和 Linux 创建应用程序,而只需编写一次代码。

  2. Web 技术: Electron 允许开发者使用他们已经熟悉的 Web 技术,如 HTML, CSS 和 JavaScript,来构建应用程序。

  3. Chromium 集成: Electron 应用将 Chromium(一个开源的 Web 浏览器项目,也是 Google Chrome 的基础)包含在内,这意味着你可以使用最新的 Web API 和功能。

  4. Node.js 集成: Electron 应用程序在其主进程和渲染进程中都集成了 Node.js,允许开发者使用 npm 包和 Node.js API。

  5. 原生 API 访问: Electron 提供了一系列的 API,允许开发者访问操作系统的底层功能,如文件系统、菜单、通知等。

1.3 一些知名的 Electron 应用

多个流行和大型的应用程序都是使用 Electron 构建的,包括但不限于:

1.4 总结

Electron 提供了一个强大且灵活的方式来构建跨平台的桌面应用程序,使得 Web 开发者无需深入学习各种平台的原生开发技术就可以构建应用。这使得许多 Web 开发者和团队可以更快速地进入桌面应用领域。

2. 环境准备

2.1 安装 Node.js 和 npm

Electron 的核心依赖于 Node.js,因此首先需要安装 Node.js 和 npm(Node.js 的包管理器)。

  1. 下载 Node.js:

    • 访问 Node.js 官方网站 https://nodejs.org/
    • 根据你的操作系统选择合适的版本进行下载。建议下载 LTS(长期支持)版本,因为它更加稳定。
  2. 安装:

    • 双击下载的安装程序,并按照提示进行安装。
  3. 验证安装:

    • 打开终端或命令提示符。
    • 输入 node -vnpm -v 来确保两者都已正确安装。
    bash
    node -v
    npm -v

2.2 Electron 的安装

安装 Electron 非常简单,只需要使用 npm 命令。

  1. 创建一个新的项目文件夹:

    bash
    mkdir my-electron-app
    cd my-electron-app
  2. 初始化 npm 项目:

    bash
    npm init

    这将启动一个交互式会话来创建一个 package.json 文件。

  3. 安装 Electron:

    bash
    npm install electron --save-dev

    这将 Electron 安装为项目的开发依赖。

2.3 快速验证 Electron 安装

  1. 创建主文件:

    在项目根目录中,创建一个名为 main.js 的文件,然后添加以下内容:

    javascript
    const { 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);
  2. 创建 HTML 文件:

    在同一目录下,创建一个名为 index.html 的文件,并添加基本的 HTML 内容,例如:

    html
    <!DOCTYPE html>
    <html>
      <head>
        <title>My Electron App</title>
      </head>
      <body>
        <h1>Hello, Electron!</h1>
      </body>
    </html>
  3. 运行 Electron 应用:

    修改 package.json 文件,将 start 脚本更改为以下内容:

    json
    "scripts": {
      "start": "electron main.js"
    }

    然后,运行以下命令启动 Electron 应用:

    bash
    npm start

    这将启动 Electron,并你应该能看到一个显示 "Hello, Electron!" 的窗口。

通过以上步骤,你已经成功地设置了 Electron 的开发环境,并验证了它的安装。

3. Electron 基础

3.1 主进程和渲染进程

在 Electron 中,每个应用有一个主进程和一个或多个渲染进程。

  1. 主进程:

    • 负责运行 package.jsonmain 脚本,并执行应用的整个生命周期。
    • 控制所有的 Web 页面和与它们的交互。
    • 只有在主进程中才能调用某些 Electron 的原生 API。
    • 一个 Electron 应用始终有一个主进程。
  2. 渲染进程:

    • 每个 Electron 的 BrowserWindow 在其自己的渲染进程中运行 Web 页面。
    • 负责页面的渲染,即页面上的用户界面。
    • 一个 Electron 应用可以有多个渲染进程。
    • 与主进程相对独立,但二者之间可以通过 IPC(进程间通讯)进行通信。

3.2 Electron 的主要模块

Electron 提供了一系列的模块来帮助开发者创建桌面应用。以下是其中的一些关键模块:

  1. app:

    • 控制应用的事件生命周期。
    • 提供了应用关闭、准备完毕等事件。
  2. BrowserWindow:

    • 创建和管理应用窗口。
    • 允许加载和渲染 Web 内容。
  3. Menu 和 MenuItem:

    • 为应用创建原生菜单。
  4. ipcMain 和 ipcRenderer:

    • 允许主进程和渲染进程之间的通信。
  5. shell:

    • 提供了与操作系统的 shell 交互的相关功能。
  6. dialog:

    • 提供了原生的对话框,如打开文件、保存文件等。

3.3 Electron 应用的生命周期

Electron 的 app 模块提供了与应用生命周期事件相关的方法和事件。

  1. app 的 'ready' 事件:

    • 当 Electron 完成初始化时触发。
    • 此时通常会创建应用窗口。
  2. app 的 'window-all-closed' 事件:

    • 当所有窗口都被关闭时触发。
    • 通常在这个事件中结束应用,除非在 macOS 中,其中通常会保持应用在 dock 中运行,直到用户显式地退出应用。
  3. app 的 'activate' 事件 (macOS only):

    • 当用户点击了应用的 dock 图标并且没有其他窗口打开时触发。
    • 通常在这个事件中重新创建一个应用窗口。

这些基础知识为你提供了创建 Electron 应用的基本框架。了解这些基础后,你可以更深入地探索 Electron 的 API 并开始构建更复杂的应用。

4. 创建第一个 Electron 应用

4.1 初始化项目

  1. 创建项目文件夹:

    bash
    mkdir my-first-electron-app
    cd my-first-electron-app
  2. 初始化 npm 项目:

    bash
    npm init -y

    这将为你的项目创建一个默认的 package.json 文件。

  3. 安装 Electron:

    bash
    npm install electron --save-dev

4.2 主文件与渲染文件

  1. 创建主文件 (main.js):

    在项目根目录中,创建一个名为 main.js 的文件。这是应用的入口点,负责创建窗口和管理应用的生命周期。

    javascript
    const { 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);
  2. 创建渲染文件 (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 方法。

例如,关闭一个窗口:

javascript
mainWindow.close();

或者最小化窗口:

javascript
mainWindow.minimize();

你还可以添加事件监听,如当窗口关闭时:

javascript
mainWindow.on("closed", () => {
  mainWindow = null;
});

4.4 运行和调试

  1. 设置启动脚本:

    修改 package.json 中的 scripts 部分,添加启动脚本:

    json
    "scripts": {
      "start": "electron main.js"
    }
  2. 运行应用:

    在终端或命令提示符中,输入以下命令:

    bash
    npm start

    此命令将启动 Electron,并显示你创建的窗口。

  3. 调试:

    Electron 使用的 Chromium 引擎内置了 DevTools,你可以直接在 Electron 应用中使用这些开发者工具进行调试。

    main.js 中,添加以下代码,使 DevTools 在应用启动时自动打开:

    javascript
    mainWindow.webContents.openDevTools();

现在你已经成功创建了一个基本的 Electron 应用,并了解了如何进行简单的调试。随着对 Electron 的深入学习,你可以开始添加更多的功能和交互,创建复杂的桌面应用程序。

5. 与原生功能交互

Electron 允许你与计算机的原生功能进行交互,这也是其作为桌面应用开发框架的优势之一。

5.1 文件系统交互

Electron 应用可以直接使用 Node.js 的 fs 模块来操作文件系统。

示例:读取文件内容

javascript
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 模块来显示原生的系统对话框,例如打开文件、保存文件、警告等。

示例:显示一个“打开文件”对话框

javascript
const { dialog } = require("electron");

const filePaths = dialog.showOpenDialogSync({
  title: "Select a file",
  properties: ["openFile"],
});

console.log(filePaths);

5.3 通知

Electron 提供了一个 Notification API 来显示桌面通知。

示例:显示一个通知

javascript
const { Notification } = require("electron");

const notification = {
  title: "Electron Notification",
  body: "Hello from Electron!",
};

new Notification(notification).show();

5.4 菜单和上下文菜单

Electron 的 MenuMenuItem 模块允许你创建原生的应用菜单和上下文菜单。

示例:创建一个应用菜单

javascript
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);

示例:创建一个上下文菜单

javascript
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 请求。

安装:

bash
npm install axios

示例:使用 Axios 发起 GET 请求

javascript
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 请求。

  1. WebSockets:

    使用 ws 或其他类似的库,你可以创建 WebSocket 连接,实现双向通信。

    示例

    javascript
    const 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}`);
    });
  2. 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 性能优化建议

  1. 减少包大小:

    • 使用工具如 webpack 来打包和优化代码。
    • 剔除不必要的依赖和模块。
  2. 使用 lazy-loading:

    • 只有当需要时才加载某些模块或资源。
  3. 优化渲染进程:

    • 避免长时间的同步操作。
    • 使用 requestAnimationFrame 对动画和持续的 UI 更新进行优化。
  4. 内存管理:

    • 定期查看和检测内存使用情况。
    • 使用工具如 Chrome DevTools 进行内存分析。

7.2 Electron 安全建议

  1. 限制 Node.js 功能:

    • 在渲染进程中尽量禁用 nodeIntegration,并使用 preload 脚本来公开所需的功能。
  2. 禁用远程模块:

    • 设置 enableRemoteModulefalse,以阻止渲染进程访问 Electron APIs。
  3. 验证和清理加载的内容:

    • 只加载和执行来自可信来源的代码和内容。
    • 不要执行未经验证的远程代码。
  4. 使用上下文隔离:

    • 设置 contextIsolationtrue,以确保渲染进程中的 Electron 和 Node.js 功能与页面内容完全隔离。

7.3 CSP (内容安全策略) 的实施

内容安全策略 (CSP) 是一个额外的安全层,它可以帮助检测和缓解某些类型的攻击,如跨站脚本 (XSS) 和数据注入攻击。

  1. 设置 CSP 元标签:

    在应用的 HTML 头部添加以下元标签:

    html
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self'"
    />

    这将限制脚本只能从同一个来源加载,并禁止内联脚本。

  2. 扩展和定制 CSP:

    • 根据需要扩展 CSP,例如允许加载来自特定域的图像或样式。
    • 对于更复杂的策略,可能需要结合多个 CSP 指令。
  3. 调试 CSP:

    • 如果应用中的某些内容由于 CSP 而不加载或运行,浏览器控制台将显示相关的错误消息。
    • 读取并根据这些错误消息调整 CSP。

在实施上述建议时,重要的是进行持续的审查和测试,以确保应用的性能和安全性满足预期。

8. 打包与分发

当你完成了 Electron 应用的开发,下一步是将它打包并分发给用户。这一章节将指导你如何有效地打包、分发和更新 Electron 应用。

8.1 使用 electron-builder

electron-builder 是一个完整的解决方案,用于打包和发布 Electron 应用。

安装:

bash
npm install electron-builder --save-dev

配置: 在 package.json 中添加配置部分。这里是一个基本示例:

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

打包:

bash
npm run electron-builder -- --mac --win

8.2 跨平台打包策略

  1. 目标平台: 确定你希望支持的平台(如 Windows、macOS、Linux)。

  2. 图标和资源: 为每个平台准备相应的图标和其他资源。

  3. 原生模块: 如果使用了原生 Node.js 模块,确保它们能够在所有目标平台上正确编译。

  4. 测试: 在每个目标平台上测试应用以确保其功能和性能。

8.3 自动更新

Electron 的 autoUpdater 模块允许你在应用中实现自动更新功能。与此同时,electron-builder 提供了易于使用的更新解决方案。

配置: 在 package.json 中的 build 部分配置更新服务器的 URL:

json
{
  "build": {
    ...
    "publish": {
      "provider": "github",
      "repo": "your-repo",
      "owner": "your-username",
      "private": false
    }
  }
}

实现自动更新: 在主进程的代码中:

javascript
const { autoUpdater } = require("electron-updater");

autoUpdater.checkForUpdatesAndNotify();

autoUpdater.on("update-available", () => {
  // 提示用户更新可用
});

autoUpdater.on("update-downloaded", () => {
  // 提示用户重新启动应用以完成更新
});

发布新版本: 当你发布应用的新版本时:

  1. 更新 package.json 中的版本号。
  2. 运行 electron-builder 来创建新的发布资产。
  3. 在 GitHub 或其他托管服务上发布新版本,并附加 electron-builder 生成的资产。

这样,当用户的应用下次启动时,它会自动检查、下载并提示用户安装新版本。

总之,正确地打包、分发和更新 Electron 应用是提供一个顺畅用户体验的关键部分,因此值得花时间和精力来确保这一过程的顺利进行。