0
点赞
收藏
分享

微信扫一扫

使用Electron.js构建简单应用

介绍

Electron 是一个旨在使用 JavaScript 构建桌面应用程序的框架。如果您已经是一名 JavaScript 开发人员并且不想学习一门新语言来编写桌面应用程序,那么 Electron 可能是您的不错选择。

你之前可能没有注意到,其实 Electron 在我们的电脑中无处不在。著名的 Electron 应用程序包括 VSCode、Discord、Whatsapp、Slack 等。这些应用程序的桌面版本可能看起来与它们的 Web 版本完全一样,因为使用 Electron 将现有网页应用程序导入桌面应用程序几乎为零。

在选择 Electron 作为桌面应用程序框架之前,您可能会考虑一些优缺点。

优点

  1. 对网络开发者友好
  2. 专注于设计
  3. 可扩展

缺点

  1. 打包文件大
  2. 兼容性不好

主进程和渲染进程

在开始编写 Electron 之前,我们应该先了解一下 Electron 中有哪些主进程和渲染进程。

 使用Electron.js构建简单应用_应用程序

主进程

Electron 应用程序的后端。通常,像 index.js 这样的文件包含在主进程中工作的模块。在主进程中,Node JS 用于与数据库和文件系统进行通信。如果您是一名前端开发人员并且以前没有使用过 Node JS,那完全没问题。您会发现 Node JS 看起来与 JavaScript 完全一样,而且很容易上手,这就是 Node JS 的用途。

渲染进程

Electron 应用程序的前端。通常,像 preload.js 这样的文件包含在渲染器进程中工作的模块。渲染器进程与渲染器 (Chromium) 和前端 JavaScript 进行通信。

进程间通信 (IPC)

为了在两个不同的进程之间进行通信,我们需要某种隧道。Electron 提供了一种安全的方式作为 Electron API 来实现这一点。Electron API 与 Web API 非常相似,不同之处在于它使用特殊的隧道并且后端在您的本地机器上运行。

IPC 有两种基本用法。IPC是基于事件的,所以我们应该为事件命名一个信号,并根据名称发送/接收数据。数据可以是任何可以作为函数参数传递的对象。

如果我们只需要发送一些数据而不期望响应,我们可以使用 ipcRenderer.send() 和 ipcMain.on()。

const { ipcRenderer } = require("electron");
ipcRenderer.send("first-signal", "signal1");

const { ipcMain } = require("electron");
ipcMain.on("first-signal", (e, text) => {
console.log(text); // "signal1"
})

如果我们需要响应或双向通信,我们可以改用 ipcRenderer.invoke() 和 ipcMain.handle()。请注意 ipcRenderer.invoke() 将返回一个承诺。

const { ipcRenderer } = require("electron");
ipcRenderer
.invoke("second-signal", "signal2")
.then(res => console.log(res)) // "signal2 received!"

const { ipcMain } = require("electron");
ipcMain.handle("second-signal", (e, text) => {
return `${text} received!`;
})

简单的聊天应用程序

现在我们可以开始构建一个模拟聊天的简单 Electron 应用程序。

环境

确保安装了yarn。如果您使用的是 npm,请相应地替换命令。

mkdir electron-example
cd electron-example
yarn init
yarn add electron

将以下字段添加到您的 package.json 中,以便您稍后可以调用“yarn start”来启动应用程序。

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

HTML

我们将从一个名为 index.html 的 HTML 网页加载我们的 Electron 应用程序。

<!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'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
<form id="chat-form">
<input type="text" name="chat-box" id="chat-box" />
<button type="submit" name="send-chat" id="send-chat">Send</button>
</form>
<ul id="friend-list"></ul>
<button type="button" name="get-friends" id="get-friends">My Friends</button>
<script type="module" src="init.js"></script>
</body>
</html>

以及用于事件监听器的 init.js。

document.getElementById("chat-form").addEventListener("submit", (e) => {
e.preventDefault();
window.api.sendMessage();
})
document.getElementById("get-friends").addEventListener("click", async (e) => {
const friends = await window.api.getFriends();
const friendList = document.getElementById("friend-list");
friendList.innerHTML = "";
friendList.append(...friends.map(x => {
const li = document.createElement("li");
li.innerText = `[${x.id}] ${x.name}`;
return li;
}));
})

这里我们有两个按钮,一个用于发送消息,一个用于获取好友列表。这两个函数都调用“​​window.api.xxx​​()”,接下来我们将看看它是如何工作的。

渲染进程

首先,我们将创建一个名为 App.js 的文件,用于创建一个 Electron 应用程序和一个主窗口。

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

const mainWindow = () => {
const window = new BrowserWindow({
width: 1280,
height: 720,
webPreferences: {
enableRemoteModule: true,
nodeIntegration: true,
preload: path.join(__dirname, "./preload.js")
}
});

window.on("ready-to-show", window.show);

window.loadFile("index.html");

}

app.whenReady().then(() => {
mainWindow();
})

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

这里我们告诉 Electron 在创建主窗口之前加载 preload.js,它看起来像这样:

const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("api", {
sendMessage: () => {
const chatBox = document.getElementById("chat-box");
ipcRenderer.send("send-message", chatBox.value);
chatBox.value = "";
},
getFriends: () => {
return ipcRenderer.invoke("get-friends");
}
})

window.addEventListener("DOMContentLoaded", () => {
ipcRenderer.send("main-window-ready");
})

在这里,我们定义了我们从 init.js 调用的两个 API 函数,它们执行 ipcRenderer.send() 和 ipcRenderer.invoke() 工作。我们也可以直接在浏览器控制台调用window.api进行测试。

主进程

我们会将所有代码包含在一个名为 index.js 的文件中。这是 Electron 为主进程调用的默认文件,您可以通过更改 package.json 中的“main”字段来更改它。

"use strict"

require("./App");

const { ipcMain } = require("electron");

const getMyFriends = () => {
return [
{id: 6030, name: "Twilley"},
{id: 967, name: "Wickkiser"},
{id: 5073, name: "Essick"},
{id: 8886, name: "Marotta"},
{id: 7416, name: "Banh"}
];
}

const sendMessage = (message) => {
console.log(message);
}

ipcMain
.on("main-window-ready", (e) => {
console.log("Main window is ready");
})
.on("send-message", (e, message) => {
sendMessage(message);
})

ipcMain.handle("get-friends", (e) => {
return getMyFriends();
})

然后我们就完成了应用程序的设置!添加任何你喜欢的功能,运行和测试。

 使用Electron.js构建简单应用_API_02

举报

相关推荐

0 条评论