Electron - 原生 Node 模块
Electron - 利用 Node.js 原生模块
Section titled “Electron - 利用 Node.js 原生模块”在 Electron 中,你可以完全访问 Node.js 内置模块,允许你直接从桌面应用程序与操作系统、文件系统、网络等进行交互。我们之前探讨了 fs(文件系统)模块。现在让我们看看其他有用的 Node.js 模块。
os 模块:系统信息
Section titled “os 模块:系统信息”os 模块提供了与操作系统相关的实用方法和属性。这对于根据用户的环境调整应用程序的行为或外观非常宝贵。
| 方法/属性 | 描述 |
|---|---|
os.userInfo([options]) | 返回一个包含当前用户信息(如用户名、用户 ID、组 ID、主目录和默认 shell)的对象。对于个性化设置或用户特定配置很有用。 |
os.platform() | 返回一个标识操作系统平台的字符串,例如 'darwin' (macOS)、'win32' (Windows)、'linux'。对于平台特定逻辑至关重要。 |
os.homedir() | 返回当前用户主目录的字符串路径。非常适合存储用户特定的应用程序数据或配置。 |
os.arch() | 返回一个标识 CPU 架构的字符串,例如 'x64'、'arm64'。可用于提供架构特定的二进制文件或优化。 |
os.EOL | 一个定义操作系统特定行结束标记的字符串常量(例如,Linux/macOS 上的 \n,Windows 上的 \r\n)。在写入文本文件时使用此项可确保跨平台兼容性。 |
要在你的 Electron 应用中显示这些信息,你通常会创建一个主进程文件(main.js)来设置 BrowserWindow,以及一个渲染进程文件(HTML 文件)来显示内容。出于安全考虑,最佳实践是使用预加载脚本和 contextBridge 有选择地将 Node.js 模块暴露给渲染进程。
下面是一个示例。首先,你的 main.js 文件:
const { app, BrowserWindow } = require('electron');const path = require('path');
function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), // contextIsolation 默认为 true,推荐使用 // nodeIntegration 默认为 false,推荐使用 } });
win.loadFile('index.html');}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); }});
app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); }});接下来,在同一目录下创建一个 preload.js 文件:
const { contextBridge } = require('electron');const os = require('os');
contextBridge.exposeInMainWorld('electronOS', { getUserInfo: () => os.userInfo(), getPlatform: () => os.platform(), getHomedir: () => os.homedir(), getArch: () => os.arch(), getEOL: () => os.EOL});最后,你的 index.html 文件:
<!DOCTYPE html><html><head> <title>OS Module Info</title> <meta charset="UTF-8"></head><body> <h1>Operating System Information</h1> <div id="os-info">Loading...</div> <script> const osInfoDiv = document.getElementById('os-info'); try { const userInfo = window.electronOS.getUserInfo(); const platform = window.electronOS.getPlatform(); const homedir = window.electronOS.getHomedir(); const arch = window.electronOS.getArch();
osInfoDiv.innerHTML = `User Info: ${JSON.stringify(userInfo, null, 2)}<br><br>` + `Platform: ${platform}<br>` + `User Home Directory: ${homedir}<br>` + `OS Architecture: ${arch}`; } catch (error) { osInfoDiv.textContent = 'Error accessing OS information. Make sure preload script is configured correctly.'; console.error('Error accessing OS info via contextBridge:', error); } </script></body></html>使用以下命令运行你的应用:
$ electron .应用程序窗口将显示系统信息。例如,在 Linux 系统上,你可能会看到:
User Info: { "uid": 1000, "gid": 1000, "username": "youruser", "homedir": "/home/youruser", "shell": "/bin/bash"}
Platform: linuxUser Home Directory: /home/youruserOS Architecture: x64(注意:实际输出会因你的操作系统和用户配置而异。)
net 模块:网络能力
Section titled “net 模块:网络能力”net 模块提供了一个异步网络 API,用于创建 TCP 服务器和客户端(基于流的 socket)。虽然 Electron 应用通常使用更高级别的协议如 HTTP/HTTPS(通过 fetch API 或 axios 等库)或 WebSockets 进行客户端-服务器通信,但 net 模块对于直接的 TCP socket 编程、点对点连接或与特定网络服务交互很有用。
net 模块的关键方法包括:
| 方法/类 | 描述 |
|---|---|
net.createServer([options][, connectionListener]) | 创建一个新的 TCP 服务器。connectionListener 函数会自动设置为监听 'connection' 事件,该事件在新客户端连接时触发。 |
net.createConnection(options[, connectionListener]) / net.connect(options[, connectionListener]) | 创建一个新的 net.Socket 并发起与指定地址和端口的连接。返回 socket 实例。 |
net.Server.listen(port[, host][, backlog][, callback]) | 启动服务器,使其在指定的 port 和 host 上监听连接。如果省略 host,服务器将接受来自任意 IPv4/IPv6 地址的连接。 |
net.Server.close([callback]) | 停止服务器接受新连接。允许现有连接完成。当所有连接都结束时,服务器会触发 'close' 事件。 |
net.Socket.connect(port[, host][, connectListener]) | 打开指定 socket 实例的连接。如果提供了 port 和 host,socket 将作为 TCP 客户端连接。 |
net.Socket.write(data[, encoding][, callback]) | 在 socket 上发送数据。 |
net.Socket.on('data', listener) | 当从 socket 的另一端接收到数据时触发的事件。 |
有关详细信息,请参阅 官方 Node.js net 模块文档。
让我们通过一个 Electron 应用作为 TCP 客户端连接到一个简单的 Node.js TCP 服务器的示例来演示。首先,创建 server.js 文件(使用 Node.js 运行,而不是 Electron):
const net = require('net');
const server = net.createServer((connection) => { console.log('Client Connected');
connection.on('end', () => { console.log('Client disconnected'); });
connection.on('error', (err) => { console.error('Connection error:', err.message); });
connection.write('Hello from TCP Server!\r\n'); // Echo back anything received connection.pipe(connection);});
const PORT = 8080;server.listen(PORT, () => { console.log(`TCP Server running on port ${PORT}`);});使用与 os 模块示例中相同的 main.js 文件(用于设置 BrowserWindow 并加载 index.html)。更新 index.html 以实现 TCP 客户端功能:
<!DOCTYPE html><html><head> <title>Net Module Client</title> <meta charset="UTF-8"></head><body> <h1>TCP Client</h1> <div id="status">Connecting...</div> <pre id="messages"></pre>
<script> // 重要提示:在渲染进程中直接使用 'require("net")' // 需要在 BrowserWindow 的 webPreferences 中设置 'nodeIntegration: true'。 // 出于安全原因,通常不推荐这样做。 // 对于生产应用,建议在 // 主进程中执行网络操作,并通过 IPC 和预加载脚本与渲染进程通信。 // 对于此教学示例,我们假设 nodeIntegration 可能已启用, // 或者此脚本已适配预加载脚本环境。
// 如果使用带有 contextBridge 的预加载脚本,你需要暴露 'net' 功能。 // 示例(概念性代码,假设 'electronNet' 通过 contextBridge 暴露): // const client = window.electronNet.connect({ port: 8080 });
// 直接用法(需要 nodeIntegration: true 或在支持 Node 的环境中执行): try { const net = require('net'); const statusDiv = document.getElementById('status'); const messagesPre = document.getElementById('messages');
const client = net.connect({ port: 8080 }, () => { console.log('Connection established with server!'); statusDiv.textContent = 'Connected to server!'; client.write('Hello server from Electron client!\r\n'); });
client.on('data', (data) => { console.log('Data from server:', data.toString()); messagesPre.textContent += data.toString(); // 对于此示例,我们在收到服务器的第一条消息后结束连接。 // client.end(); });
client.on('end', () => { console.log('Disconnected from server'); statusDiv.textContent = 'Disconnected from server.'; });
client.on('error', (err) => { console.error('Connection error:', err.message); statusDiv.textContent = `Connection Error: ${err.message}`; }); } catch (error) { document.getElementById('status').textContent = 'Error: Could not load net module. Ensure Node integration is enabled or use a preload script.'; console.error(error); } </script></body></html>要运行此示例:
- 在终端中启动 TCP 服务器:
node server.js。 - 在终端中(项目目录下)运行 Electron 应用:
electron .。
Electron 应用窗口将尝试连接到服务器。如果成功,它将显示“Connected to server!”,然后显示从服务器接收到的任何消息,例如“Hello from TCP Server!”。服务器控制台将记录客户端的连接和断开。
虽然为了简单起见直接在渲染进程中使用了 net 模块,但请记住,对于健壮且安全的应用程序,网络操作通常最好在主进程或实用进程中处理,并通过 IPC 将结果通信给渲染进程。