入门教程 - 构建生产力工具

知识库
知识库文档
/tech-stacks/electron/tutorial/入门教程 - 构建生产力工具.md

文档

Electron 入门教程:构建生产力工具

一、Electron 是什么?

Electron 将 Chromium 和 Node.js 整合到一个运行时中,让 Web 开发者能构建跨平台桌面应用。知名项目包括 VS Code、Slack、Figma、Notion、Discord 等都基于 Electron。

架构理解

┌─────────────────────────────────┐
│         Main Process            │
│  (Node.js, 系统级API, 窗口管理)   │
│         main.js                 │
├─────────────────────────────────┤
│      Renderer Process x N       │
│  (Chromium, HTML/CSS/JS, 不能   │
│   直接访问Node, 需preload桥接)    │
└─────────────────────────────────┘
  • 主进程:每个应用只有一个,负责管理窗口、系统托盘、菜单等
  • 渲染进程:每个窗口一个,运行网页内容,与主进程通过 IPC 通信

二、分步构建一个任务管理器

第一步:项目初始化

npm init -y
npm install electron --save-dev

第二步:主进程(窗口管理 + 系统托盘)

// main.js
const { app, BrowserWindow, Tray, Menu, ipcMain, Notification } = require('electron');
const path = require('path');

let mainWindow, tray;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 700,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
    },
    titleBarStyle: 'hiddenInset', // macOS 风格
  });
  mainWindow.loadFile('index.html');
}

// 系统托盘
function createTray() {
  tray = new Tray(path.join(__dirname, 'icon.png'));
  const contextMenu = Menu.buildFromTemplate([
    { label: '显示窗口', click: () => mainWindow.show() },
    { label: '退出', click: () => app.quit() },
  ]);
  tray.setToolTip('我的任务管理器');
  tray.setContextMenu(contextMenu);
}

第三步:数据持久化(主进程)

const fs = require('fs').promises;
const DATA_PATH = path.join(app.getPath('userData'), 'tasks.json');

ipcMain.handle('load-tasks', async () => {
  try {
    const data = await fs.readFile(DATA_PATH, 'utf-8');
    return JSON.parse(data);
  } catch {
    return []; // 文件不存在时返回空数组
  }
});

ipcMain.handle('save-tasks', async (event, tasks) => {
  await fs.writeFile(DATA_PATH, JSON.stringify(tasks, null, 2));
  return true;
});

第四步:Preload 安全桥

// preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('app', {
  loadTasks: () => ipcRenderer.invoke('load-tasks'),
  saveTasks: (tasks) => ipcRenderer.invoke('save-tasks', tasks),
  onReminder: (callback) => ipcRenderer.on('reminder', callback),
});

第五步:渲染进程 UI

<!-- index.html 核心结构 -->
<div id="app">
  <input id="task-input" placeholder="添加新任务..." />
  <button id="add-btn">添加</button>
  <ul id="task-list"></ul>
</div>
<script src="renderer.js"></script>

第六步:打包分发

使用 Electron Forge:

npm install --save-dev @electron-forge/cli
npx electron-forge import
npm run make  # 生成 .exe / .dmg / .deb

三、常见陷阱与最佳实践

  1. 永远不要禁用 contextIsolation——这是最重要的安全防线
  2. 大文件操作用 Worker 线程,避免阻塞主进程
  3. 自动更新使用 electron-updater 实现
  4. 内存泄漏:每个窗口都是独立进程,及时释放关闭窗口的引用
  5. IPC 通信数据需序列化,不能传递函数或复杂对象引用

四、思考题

  1. 如何在不关闭窗口的情况下隐藏到系统托盘?
  2. app.getPath('userData') 在不同操作系统上分别对应什么目录?
  3. 为什么 Electron 不适合做 CPU 密集型后端服务?

信息

路径
/tech-stacks/electron/tutorial/入门教程 - 构建生产力工具.md
更新时间
2026/5/31