Skip to content

Electron 调试与性能

开发调试、性能优化、生产日志与常见问题

目录


开发调试

渲染进程 DevTools

typescript
// 开发环境自动打开
if (process.env.NODE_ENV === 'development') {
  win.webContents.openDevTools();
}

// 或通过快捷键 Cmd+Option+I (macOS) / Ctrl+Shift+I (Windows)

主进程调试

方式一:VS Code 配置

json
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Main Process",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
      "windows": { "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd" },
      "args": [".", "--remote-debugging-port=9222"],
      "outputCapture": "std"
    }
  ]
}

方式二:Chrome 附加

bash
electron . --inspect=9222
# Chrome 打开 chrome://inspect,附加到 Node 目标

Source Map

javascript
// webpack / vite 构建时生成 source map
// main 进程
module.exports = {
  devtool: 'source-map',
  target: 'electron-main'
};

// 渲染进程
// Vite 默认开发时启用,生产可配置 sourcemap: true

性能优化

多窗口内存管理

typescript
// 窗口关闭时释放引用
win.on('closed', () => {
  mainWindow = null; // 避免内存泄漏
});

// 不可见时暂停部分逻辑
win.on('hide', () => {
  win.webContents.send('pause-heavy-work');
});
win.on('show', () => {
  win.webContents.send('resume-heavy-work');
});

WebContents 生命周期

typescript
// 后台页面可降低优先级
win.webContents.on('did-finish-load', () => {
  win.webContents.setBackgroundThrottling(true); // 后台节流
});

// 不再需要的窗口及时销毁
secondaryWin.close();

懒加载与代码分割

  • 渲染进程:使用动态 import()、路由懒加载
  • 主进程:按需 require,避免启动时加载全部模块
  • 预加载脚本:保持精简,只暴露必要 API

原生模块按平台加载

javascript
// 只打包当前平台的原生模块
const nativeModule = process.platform === 'win32'
  ? require('./native-win')
  : require('./native-darwin');

生产日志与崩溃上报

electron-log

typescript
const log = require('electron-log');

log.info('应用启动');
log.error('错误信息', error);
log.warn('警告');

// 日志文件位置
// macOS: ~/Library/Logs/{app name}/main.log
// Windows: %USERPROFILE%\AppData\Roaming\{app name}\logs\main.log

崩溃上报

typescript
const { crashReporter } = require('electron');

crashReporter.start({
  productName: 'MyApp',
  companyName: 'MyCompany',
  submitURL: 'https://your-server.com/crash-report',
  uploadToServer: true
});

// 崩溃时自动上传 dump,可在服务端用 symbolicate 解析

未捕获异常

typescript
process.on('uncaughtException', (err) => {
  log.error('Uncaught exception:', err);
  // 上报后可选退出
});

process.on('unhandledRejection', (reason, promise) => {
  log.error('Unhandled rejection:', reason);
});

常见问题与排查

白屏

原因排查解决
路径错误检查 loadURL / loadFile 路径使用 path.join(__dirname, ...)
打包后 __dirname 变化开发正常、打包白屏使用 app.getAppPath()process.resourcesPath
CSP 阻止控制台报 CSP 错误放宽或修正 CSP
渲染进程报错DevTools 查看 Console修复 JS 错误

打包后路径问题

typescript
// 开发:__dirname 为源码目录
// 打包:__dirname 在 asar 内,路径不同

const isDev = !app.isPackaged;
const preloadPath = isDev
  ? path.join(__dirname, 'preload.js')
  : path.join(process.resourcesPath, 'app.asar', 'preload.js');
// 或使用 electron-builder extraResources 将 preload 放到 asar 外

ASAR 调试

bash
# 解包 asar 查看内容
npx asar extract app.asar extracted/

预加载脚本不生效

  • 确认 webPreferences.preload 路径正确
  • 确认 contextIsolation: true 时使用 contextBridge
  • 检查 preload 是否有语法错误(主进程控制台)

高频面试题

Q1: 如何调试主进程?

使用 VS Code 的 launch 配置,或 electron . --inspect=9222 后用 Chrome DevTools 附加。

Q2: 打包后白屏常见原因?

路径问题(__dirname 在 asar 内)、资源未包含进 files、CSP 过严、渲染进程 JS 报错。

Q3: electron-log 的日志存在哪?

  • macOS: ~/Library/Logs/{app name}/
  • Windows: %USERPROFILE%\AppData\Roaming\{app name}\logs\

前端面试知识库