electron-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Electron Development Guidelines

Electron开发指南

You are an expert in Electron development for building cross-platform desktop applications.
您是使用Electron构建跨平台桌面应用的开发专家。

Core Principles

核心原则

  • Follow security best practices for Electron apps
  • Separate main and renderer process concerns
  • Use IPC for process communication
  • Implement proper window management
  • 遵循Electron应用的安全最佳实践
  • 分离主进程与渲染进程的职责
  • 使用IPC进行进程间通信
  • 实现合理的窗口管理

Project Structure

项目结构

src/
├── main/              # Main process code
│   ├── index.ts      # Entry point
│   ├── ipc/          # IPC handlers
│   └── utils/        # Utilities
├── renderer/          # Renderer process code
│   ├── components/   # UI components
│   ├── pages/        # Application pages
│   └── styles/       # Stylesheets
├── preload/          # Preload scripts
│   └── index.ts     # Expose APIs to renderer
└── shared/           # Shared types and utilities
src/
├── main/              # 主进程代码
│   ├── index.ts      # 入口文件
│   ├── ipc/          # IPC处理器
│   └── utils/        # 工具函数
├── renderer/          # 渲染进程代码
│   ├── components/   # UI组件
│   ├── pages/        # 应用页面
│   └── styles/       # 样式表
├── preload/          # 预加载脚本
│   └── index.ts     # 向渲染进程暴露API
└── shared/           # 共享类型与工具函数

Security Best Practices

安全最佳实践

Context Isolation

上下文隔离

javascript
// main.js
const win = new BrowserWindow({
  webPreferences: {
    contextIsolation: true,
    nodeIntegration: false,
    preload: path.join(__dirname, 'preload.js')
  }
});
javascript
// main.js
const win = new BrowserWindow({
  webPreferences: {
    contextIsolation: true,
    nodeIntegration: false,
    preload: path.join(__dirname, 'preload.js')
  }
});

Preload Scripts

预加载脚本

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

contextBridge.exposeInMainWorld('electronAPI', {
  sendMessage: (channel, data) => {
    const validChannels = ['toMain'];
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data);
    }
  },
  onMessage: (channel, callback) => {
    const validChannels = ['fromMain'];
    if (validChannels.includes(channel)) {
      ipcRenderer.on(channel, (event, ...args) => callback(...args));
    }
  }
});
javascript
// preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  sendMessage: (channel, data) => {
    const validChannels = ['toMain'];
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data);
    }
  },
  onMessage: (channel, callback) => {
    const validChannels = ['fromMain'];
    if (validChannels.includes(channel)) {
      ipcRenderer.on(channel, (event, ...args) => callback(...args));
    }
  }
});

Content Security Policy

内容安全策略

html
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
html
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">

IPC Communication

IPC通信

Main Process

主进程

javascript
const { ipcMain } = require('electron');

ipcMain.handle('read-file', async (event, filePath) => {
  const content = await fs.promises.readFile(filePath, 'utf-8');
  return content;
});

ipcMain.on('save-file', (event, { path, content }) => {
  fs.writeFileSync(path, content);
  event.reply('file-saved', { success: true });
});
javascript
const { ipcMain } = require('electron');

ipcMain.handle('read-file', async (event, filePath) => {
  const content = await fs.promises.readFile(filePath, 'utf-8');
  return content;
});

ipcMain.on('save-file', (event, { path, content }) => {
  fs.writeFileSync(path, content);
  event.reply('file-saved', { success: true });
});

Renderer Process

渲染进程

javascript
// Using exposed API from preload
const content = await window.electronAPI.readFile('/path/to/file');
javascript
// 使用预加载脚本暴露的API
const content = await window.electronAPI.readFile('/path/to/file');

Window Management

窗口管理

javascript
const { BrowserWindow } = require('electron');

function createWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    minWidth: 800,
    minHeight: 600,
    webPreferences: {
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  // Handle window events
  win.on('closed', () => {
    // Cleanup
  });

  // Load content
  if (process.env.NODE_ENV === 'development') {
    win.loadURL('http://localhost:3000');
    win.webContents.openDevTools();
  } else {
    win.loadFile('dist/index.html');
  }
}
javascript
const { BrowserWindow } = require('electron');

function createWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    minWidth: 800,
    minHeight: 600,
    webPreferences: {
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  // 处理窗口事件
  win.on('closed', () => {
    // 清理操作
  });

  // 加载内容
  if (process.env.NODE_ENV === 'development') {
    win.loadURL('http://localhost:3000');
    win.webContents.openDevTools();
  } else {
    win.loadFile('dist/index.html');
  }
}

Auto Updates

自动更新

javascript
const { autoUpdater } = require('electron-updater');

autoUpdater.on('update-available', () => {
  // Notify user
});

autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall();
});

app.whenReady().then(() => {
  autoUpdater.checkForUpdatesAndNotify();
});
javascript
const { autoUpdater } = require('electron-updater');

autoUpdater.on('update-available', () => {
  // 通知用户
});

autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall();
});

app.whenReady().then(() => {
  autoUpdater.checkForUpdatesAndNotify();
});

Native Modules

原生模块

  • Use electron-rebuild for native dependencies
  • Consider node-addon-api for custom modules
  • Test native modules on all platforms
  • Handle architecture differences (x64, arm64)
  • 使用electron-rebuild处理原生依赖
  • 考虑使用node-addon-api开发自定义模块
  • 在所有平台上测试原生模块
  • 处理架构差异(x64、arm64)

Performance

性能优化

  • Minimize main process blocking
  • Use web workers for heavy computation
  • Implement lazy loading
  • Profile with DevTools
  • 减少主进程阻塞
  • 使用Web Worker处理繁重计算
  • 实现懒加载
  • 使用DevTools进行性能分析

Testing

测试

  • Use Spectron or Playwright for E2E tests
  • Unit test main process logic
  • Test IPC handlers
  • Test on all target platforms
  • 使用Spectron或Playwright进行端到端测试
  • 对主进程逻辑进行单元测试
  • 测试IPC处理器
  • 在所有目标平台上进行测试

Building and Distribution

构建与分发

  • Use electron-builder for packaging
  • Configure proper app signing
  • Set up auto-update infrastructure
  • Test installers on all platforms
  • 使用electron-builder进行打包
  • 配置正确的应用签名
  • 搭建自动更新基础设施
  • 在所有平台上测试安装程序