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\