Electron入门教程:从安装到进程通信详解

Viewed 0

官网: https://www.electronjs.org/zh/

安装依赖

首先初始化 package.json 文件,然后安装 Electron 作为开发依赖。

pnpm init
pnpm add -D electron

如果安装过程中遇到网络问题,可以通过配置 npm 镜像来解决。打开 npm 的配置文件(可通过 npm config edit 命令),在空白处添加以下淘宝镜像地址:

registry=https://registry.npmmirror.com
electron_mirror=https://cdn.npmmirror.com/binaries/electron/
electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/

手动配置完成后,重新运行 pnpm add -D electron 即可成功安装。

启动一个简单的项目

  1. 修改 package.json 文件,更新 main 字段指向主进程脚本,并在 scripts 中添加启动命令。注意 authordescription 字段为必填。
{
  "name": "Electron-补习所",
  "version": "1.0.0",
  "description": "electron-test",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [],
  "author": "wangfan",
  "license": "ISC",
  "devDependencies": {
    "electron": "^32.1.2"
  }
}
  1. 在根目录新建 main.js 文件作为主进程入口。监听应用的 ready 事件,创建一个浏览器窗口并加载指定 URL。
const { app, BrowserWindow } = require("electron");

app.on("ready", () => {
  const win = new BrowserWindow({
    width: 500,
    height: 500,
    autoHideMenuBar: true,
  });
  win.loadURL('https://www.electronjs.org/zh/');
});

加载本地页面

在根目录新建 pages 文件夹,并在其中创建 index.htmlindex.css 文件,编写简单的页面内容。接着修改 main.js,使用 loadFile 方法加载本地页面。

const { app, BrowserWindow } = require("electron");

app.on("ready", () => {
  const win = new BrowserWindow({
    width: 500,
    height: 500,
    autoHideMenuBar: true,
    alwaysOnTop: true
  });
  win.loadFile('./pages/index.html');
});

启动项目后,如果开发者工具出现内容安全策略(CSP)警告,需要在 HTML 的 <head> 部分配置 CSP。具体配置可参考 MDN 文档。

完善窗口行为

为了管理窗口的生命周期,将创建窗口的逻辑封装为 createWindow 函数。根据操作系统差异,在 Windows 系统上,所有窗口关闭时退出应用;在 macOS 系统上,应用被激活时若没有窗口则自动创建一个。

const { app, BrowserWindow } = require("electron");

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 500,
    autoHideMenuBar: true,
  });
  win.loadFile("./pages/index.html");
}

app.on("ready", () => {
  createWindow();
  app.on("window-all-closed", () => {
    if (process.platform !== "darwin") app.quit();
  });
});

app.on("activate", () => {
  if (BrowserWindow.getAllWindows().length === 0) createWindow();
});

自动启动应用

为了避免每次修改主进程代码后手动重启应用,可以安装 nodemon 来实现自动重启。

pnpm i nodemon -D

package.jsonscripts 中修改启动命令:

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

还可以在根目录创建 nodemon.json 配置文件,指定监视的文件类型,实现主进程或页面文件修改后自动重启。

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

主进程与渲染进程

在 Electron 中,主进程只有一个(即 main.js,运行在 Node.js 环境),而渲染进程可以有多个(即每个浏览器窗口中的 Web 页面,运行在 Web 环境)。两者环境隔离,不能直接互访 API。

预加载脚本(如 preload.js)作为桥梁,它在渲染进程之前运行,可以访问部分 Node.js API。通过 contextBridge 可以向渲染进程暴露自定义的全局对象。

主进程中加载预加载脚本的绝对路径:

const path = require("path");
const win = new BrowserWindow({
  webPreferences: {
    preload: path.resolve(__dirname, './preload.js'),
  }
});

预加载脚本示例,向渲染进程暴露一个 myAPI 对象:

const { contextBridge } = require("electron");
contextBridge.exposeInMainWorld("myAPI", {
  mytext: "这是暴露的变量,预加载进程可使用部分nodeAPI",
  version: process.version
});

在渲染进程的 JavaScript 文件中,可以直接访问 window.myAPImyAPI

进程通讯(IPC)

进程间通信(IPC)是 Electron 的核心功能,允许主进程和渲染进程交换数据。

渲染进程向主进程通信(单向)

例如,实现点击按钮在 D 盘创建文件。在渲染进程中,通过预加载脚本暴露的函数发送消息。

渲染进程 (render.js):

setBtn.onclick = () => {
  myAPI.saveFile(input.value);
};

预加载脚本 (preload.js):

const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("myAPI", {
  saveFile: (data) => {
    ipcRenderer.send("file-save", data);
  },
});

主进程 (main.js) 监听该事件并执行文件写入操作:

const { ipcMain } = require("electron");
const fs = require("fs");
function writeFile(_, data) {
  fs.writeFileSync("D:/hello.txt", data);
}
ipcMain.on("file-save", writeFile);

渲染进程向主进程通信(双向)

例如,读取 D 盘文件内容。这需要使用 ipcRenderer.invoke 发送请求并返回 Promise。

渲染进程 (render.js):

getBtn.onclick = async () => {
  let txt = await myAPI.readFile();
  console.log(txt);
};

预加载脚本 (preload.js):

contextBridge.exposeInMainWorld("myAPI", {
  readFile: () => {
    return ipcRenderer.invoke("file-read");
  },
});

主进程 (main.js) 处理请求并返回结果:

function readFile() {
  return fs.readFileSync("D:/hello.txt").toString();
}
ipcMain.handle("file-read", readFile);

打包应用

使用 electron-builder 进行应用打包。

pnpm install electron-builder -D

package.json 中配置打包信息:

{
  "scripts": {
    "build": "electron-builder"
  },
  "build": {
    "appId": "myelectron-app",
    "win": {
      "icon": "./logo.ico",
      "target": [{
        "target": "nsis",
        "arch": ["x64"]
      }]
    },
    "nsis": {
      "oneClick": false,
      "perMachine": true,
      "allowToChangeInstallationDirectory": true
    }
  }
}

运行 pnpm run build 后,会在 dist 目录下生成安装包。

0 Answers