🚀 集成 Node.js 模块到 Electron 中:实现原生功能调用
Electron 的强大之处在于它融合了浏览器技术和 Node.js,可以让我们在桌面应用中调用原生功能。本文将带你实战演练如何在 Electron 中集成 Node.js 模块,实现如文件操作、系统信息读取等原生能力的调用。
📦 一、为什么要集成 Node.js 模块?
在 Electron 应用中,集成 Node.js 模块可以实现以下功能:
- 访问文件系统(如读写文件)
- 使用系统命令(如
child_process
执行) - 获取硬件信息(如 CPU、内存)
- 引入第三方模块(如
fs-extra
、node-fetch
)
这种能力为我们构建高性能桌面工具和生产力应用提供了基础。
🛠️ 二、项目准备
1. 初始化 Electron 项目
npm init -y
npm install electron --save-dev
2. 目录结构示例
my-electron-app/
├── main.js # 主进程
├── preload.js # 预加载脚本
├── renderer.html # 渲染进程
├── package.json
🔌 三、主进程中引入 Node 模块
主进程(main.js
)可以无缝使用任何 Node 模块:
// main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const os = require('os'); // Node.js 原生模块
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: __dirname + '/preload.js',
contextIsolation: true,
}
});
win.loadFile('renderer.html');
}
// 监听渲染进程的请求
ipcMain.handle('get-os-info', () => {
return {
platform: os.platform(),
cpus: os.cpus(),
totalmem: os.totalmem()
};
});
app.whenReady().then(createWindow);
🌉 四、通过 Preload 暴露接口给前端
出于安全考虑,我们推荐使用 contextBridge
暴露接口:
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('nativeAPI', {
getOSInfo: () => ipcRenderer.invoke('get-os-info')
});
🎨 五、在前端页面调用 Node 功能
<!-- renderer.html -->
<!DOCTYPE html>
<html>
<head><title>Electron Node集成</title></head>
<body>
<h1>系统信息</h1>
<button id="btn">获取信息</button>
<pre id="output"></pre>
<script>
document.getElementById('btn').onclick = async () => {
const info = await window.nativeAPI.getOSInfo();
document.getElementById('output').innerText = JSON.stringify(info, null, 2);
};
</script>
</body>
</html>
点击按钮后,将在页面中显示当前系统的 CPU、平台、内存等信息。
🧩 六、集成第三方 Node 模块示例(如 fs-extra)
安装:
npm install fs-extra
主进程添加:
const fs = require('fs-extra');
ipcMain.handle('read-file', async (_e, path) => {
try {
const content = await fs.readFile(path, 'utf-8');
return { success: true, content };
} catch (err) {
return { success: false, error: err.message };
}
});
预加载暴露:
contextBridge.exposeInMainWorld('fileAPI', {
readFile: (path) => ipcRenderer.invoke('read-file', path)
});
渲染进程调用:
const result = await window.fileAPI.readFile('/path/to/file.txt');
if (result.success) console.log(result.content);
🔒 七、安全注意事项
- 禁用
nodeIntegration
- 使用
contextIsolation: true
- 使用
preload.js
白名单暴露 API - 对传入的文件路径、参数进行校验(避免命令注入)
✅ 八、总结
通过合理设计,我们可以:
- 在主进程中集成任意 Node.js 模块
- 通过
ipc
+preload
将原生功能暴露给渲染进程 - 保持 Electron 应用安全性与功能性的平衡