Skip to content

Electron 入门指南 🚀

什么是 Electron? 🤔

Electron = Chromium + Node.js + Native APIs

  • 🌐 Chromium:提供强大的 Web 渲染引擎,使用熟悉的 HTML/CSS/JS 构建界面
  • 🛠️ Node.js:提供文件系统访问等底层能力
  • 🔌 Native APIs:提供跨平台和原生系统集成能力

为什么选择 Electron? 💡

  • ✅ 跨平台:一次编写,到处运行(Windows/macOS/Linux)
  • ✅ 开发效率高:使用熟悉的 Web 技术栈
  • ✅ 活跃的社区:大量可用的资源和第三方库
  • ✅ 成熟的生态:VSCode、Slack、Discord 等知名应用都在使用

环境搭建 🛠️

安装 Electron

sh
# 安装开发依赖
npm install electron --save-dev

# 安装 32 位版本(推荐:可同时支持 32/64 位系统)
npm install --arch=ia32 --platform=win32 electron

# 验证安装
electron --version

# 启动 electron
npx electron

创建你的第一个 Electron 应用 🎉

  1. 项目结构:
my-electron-app/
├── package.json
├── main.js
└── index.html
  1. 主进程文件 (main.js):
javascript
const { app, BrowserWindow } = require('electron')
const path = require('path')
// 在全局范围声明,防止被垃圾回收
let mainWindow = null  

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  })

  mainWindow.loadFile('index.html')
  
  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

app.whenReady().then(() => {
  createWindow()

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

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
  1. 渲染进程文件 (index.html):
html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello Electron!</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
    <h1>👋 Hello Electron!</h1>
    <p>Welcome to your first Electron application.</p>
</body>
</html>
  1. 配置 package.json:
json
{
  "name": "my-electron-app",
  "version": "1.0.0",
  "description": "My first Electron application",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder"
  },
  "devDependencies": {
    "electron": "^28.0.0",
    "electron-builder": "^24.9.1"
  }
}

Electron 架构详解 🏗️

进程模型

  1. 主进程 (Main Process)

    • 管理应用生命周期
    • 创建原生界面
    • 管理渲染进程

    常用模块和 API:

    javascript
    // app 模块:控制应用生命周期
    const { app } = require('electron')
    app.whenReady()  // 应用就绪
    app.quit()       // 退出应用
    
    // BrowserWindow 模块:创建和控制窗口
    const { BrowserWindow } = require('electron')
    const win = new BrowserWindow({
      width: 800,
      height: 600,
      webPreferences: {
        nodeIntegration: true, // 启用 Node.js 集成
      }
    })
    
    // dialog 模块:系统对话框
    const { dialog } = require('electron')
    dialog.showOpenDialog({
      properties: ['openFile', 'multiSelections']
    })
    
    // Menu 模块:创建原生菜单
    const { Menu } = require('electron')
    const template = [
      {
        label: '文件',
        submenu: [
          { label: '新建', click: () => { /* ... */ } },
          { label: '打开', click: () => { /* ... */ } }
        ]
      }
    ]
    const menu = Menu.buildFromTemplate(template)
    Menu.setApplicationMenu(menu)
  2. 渲染进程 (Renderer Process)

    • 运行网页内容
    • 每个窗口独立进程
    • 可访问 Node.js API

    常用模块和 API:

    javascript
    // 预加载脚本中的 API
    const { contextBridge } = require('electron')
    
    // 暴露安全的 API 到渲染进程
    contextBridge.exposeInMainWorld('electronAPI', {
      // 文件操作
      readFile: async (filePath) => {
        return await fs.promises.readFile(filePath, 'utf8')
      },
      
      // 系统操作
      getSystemInfo: () => {
        return {
          platform: process.platform,
          arch: process.arch,
          version: process.version
        }
      },
      
      // 窗口操作
      minimize: () => ipcRenderer.send('window-minimize'),
      maximize: () => ipcRenderer.send('window-maximize')
    })

进程间通信 (IPC)

javascript
// 主进程
const { ipcMain } = require('electron')

// 处理异步消息
ipcMain.on('async-message', (event, arg) => {
  event.reply('async-reply', '异步消息回复')
})

// 处理同步消息
ipcMain.on('sync-message', (event, arg) => {
  event.returnValue = '同步消息回复'
})

// 处理调用请求
ipcMain.handle('invoke-message', async (event, arg) => {
  return '这是 invoke 的结果'
})

// 渲染进程
const { ipcRenderer } = require('electron')

// 发送异步消息
ipcRenderer.send('async-message', '异步消息')
ipcRenderer.on('async-reply', (event, arg) => {
  console.log(arg)
})

// 发送同步消息
const response = ipcRenderer.sendSync('sync-message', '同步消息')

// 使用 invoke 调用
const result = await ipcRenderer.invoke('invoke-message', '参数')

常用系统功能集成

javascript
// 主进程
const { shell, clipboard, powerMonitor } = require('electron')

// 系统集成示例
class SystemIntegration {
  // 打开外部链接
  openExternal(url) {
    shell.openExternal(url)
  }
  
  // 复制到剪贴板
  copyToClipboard(text) {
    clipboard.writeText(text)
  }
  
  // 监听系统电源状态
  monitorPower() {
    powerMonitor.on('suspend', () => {
      console.log('系统即将休眠')
    })
    
    powerMonitor.on('resume', () => {
      console.log('系统已恢复')
    })
  }
}

最佳实践 💪

安全性建议

  • ✅ 始终启用上下文隔离
  • ✅ 禁用 nodeIntegration(除非必要)
  • ✅ 使用预加载脚本定义安全的 API
  • ✅ 实施内容安全策略(CSP)

性能优化

  • 🚀 使用 V8 代码缓存
  • 🚀 懒加载模块
  • 🚀 避免不必要的重绘
  • 🚀 合理使用进程通信

打包与发布 📦

sh
# 安装打包工具
npm install electron-builder --save-dev

# 配置打包脚本
"scripts": {
  "build": "electron-builder"
}

electron-builder 配置示例

json
{
  "build": {
    "appId": "com.example.app",
    "mac": {
      "category": "public.app-category.developer-tools"
    },
    "win": {
      "target": ["nsis", "portable"]
    },
    "linux": {
      "target": ["AppImage", "deb"]
    }
  }
}

技术选型对比

对比维度ElectronNativeQtNW.js
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
包体积❌❌ (50MB+)✅✅✅ (<5MB)✅✅ (20MB+)❌❌ (50MB+)
原生体验⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
跨平台能力✅✅✅✅✅✅✅✅✅✅✅✅✅✅
开发效率✅✅✅✅✅❌❌✅✅✅✅✅✅✅✅
社区活跃度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

常见问题与解决方案 🔧

  1. 白屏问题

    • 检查文件路径
    • 确保资源加载完成
    • 使用加载动画
  2. 内存泄漏

    • 及时清理事件监听
    • 关闭窗口时清理资源
    • 使用 Chrome DevTools 进行内存分析

学习资源 📚

结语 🎉

Electron 为桌面应用开发提供了一个强大而灵活的解决方案。虽然它在包体积和性能上有一些劣势,但其开发效率和跨平台能力使其成为现代桌面应用开发的重要选择。