主题切换
附录 B:调试技巧大全
调试桌面应用比 Web 开发更复杂——你需要同时面对主进程(Node.js 运行时)和渲染进程(Chromium 环境)。本附录系统梳理 Electron 调试的完整方法论,助你快速定位问题。
B.1 主进程调试
VS Code 调试配置
在项目根目录创建 .vscode/launch.json:
json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Main Process",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"args": [".", "--remote-debugging-port=9223"],
"env": {
"NODE_ENV": "development"
},
"console": "integratedTerminal",
"skipFiles": [
"<node_internals>/**"
]
}
]
}按 F5 即可在 VS Code 中调试主进程,支持断点、变量查看和调用堆栈。
Chrome DevTools 调试主进程
bash
# 启动应用时开启远程调试
electron . --inspect=5858
# 或启动时立即中断(第一行代码处)
electron . --inspect-brk=5858然后在 Chrome 浏览器中打开 chrome://inspect,点击 Configure 添加 localhost:5858,即可看到 Node.js 目标。
B.2 渲染进程调试
打开 DevTools
javascript
// 开发环境下自动打开 DevTools
const win = new BrowserWindow({
webPreferences: {
devTools: true
}
})
if (process.env.NODE_ENV === 'development') {
win.webContents.openDevTools()
}使用 Vue DevTools
bash
npm install --save-dev vite-plugin-vue-devtoolsjavascript
// vite.renderer.config.ts
import VueDevTools from 'vite-plugin-vue-devtools'
export default {
plugins: [VueDevTools(), vue()]
}远程调试真机/测试机
javascript
// 启动时允许远程调试
app.commandLine.appendSwitch('remote-debugging-address', '0.0.0.0')
app.commandLine.appendSwitch('remote-debugging-port', '9222')然后在另一台电脑的 Chrome 中访问 http://目标IP:9222 即可远程调试。
B.3 Preload 脚本调试
Preload 脚本运行在一个特殊的隔离环境中,调试较为困难。推荐方法:
使用 console 输出 + 主进程转发
javascript
// preload.js
const log = (...args) => {
console.log('[Preload]', ...args)
}
log('Preload 脚本已加载', { versions: process.versions })在渲染进程的 DevTools Console 中即可看到 [Preload] 前缀的日志。
在 Preload 中暴露调试 API
javascript
// preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('debug', {
log: (msg) => ipcRenderer.send('debug:log', msg),
getPreloadInfo: () => ({
loadedAt: Date.now(),
contextIsolation: true,
nodeIntegration: false
})
})javascript
// renderer.js
console.log(window.debug.getPreloadInfo())B.4 生产环境调试
日志系统
生产环境无法打开 DevTools,需要依赖日志:
javascript
const log = require('electron-log')
// 配置日志文件位置
log.transports.file.resolvePath = () => {
return path.join(app.getPath('logs'), 'main.log')
}
// 分级日志
log.info('应用启动', { version: app.getVersion() })
log.warn('配置缺失,使用默认值')
log.error('IPC 调用失败', error)日志文件位置:
- Windows:
%APPDATA%\YourApp\logs\ - macOS:
~/Library/Logs/YourApp/ - Linux:
~/.config/YourApp/logs/
崩溃报告分析
集成 Sentry 后,生产环境的崩溃会自动上报:
javascript
const Sentry = require('@sentry/electron/main')
Sentry.init({
dsn: 'YOUR_DSN',
beforeSend(event) {
// 附加应用状态信息
event.extra = {
...event.extra,
appVersion: app.getVersion(),
userDataPath: app.getPath('userData')
}
return event
}
})B.5 常见问题排查
白屏问题
| 可能原因 | 排查方法 | 解决方案 |
|---|---|---|
| 加载路径错误 | 检查 loadFile/loadURL 路径 | 使用 path.join(__dirname, 'renderer/index.html') |
| 打包后路径丢失 | 检查 __dirname 行为 | 设置 nodeIntegration: false + contextIsolation: true |
| 渲染进程报错 | DevTools Console | 修复 JS 错误,处理 CSP 限制 |
| 内存不足 | 任务管理器查看内存 | 优化内存使用,减少同时打开的窗口 |
窗口不显示
javascript
// 检查窗口是否被最小化到托盘
win.on('show', () => {
console.log('窗口已显示')
})
win.on('ready-to-show', () => {
console.log('内容已加载,准备显示')
win.show()
})
// 强制显示并聚焦
win.showInactive()
win.focus()IPC 无响应
javascript
// 主进程端:检查监听器是否注册
console.log(ipcMain.eventNames()) // 查看所有已注册的事件
// 渲染进程端:检查 preload 是否正确暴露
console.log(window.electronAPI) // 确认 API 对象存在
// 检查频道名称是否匹配(大小写敏感)
ipcRenderer.invoke('dialog:openFile') // 主进程必须用完全相同的名称监听应用启动后崩溃
bash
# 查看详细错误信息
electron . --enable-logging
# Windows 下查看事件查看器
eventvwr.msc # 应用程序日志
# macOS 下查看崩溃报告
open ~/Library/Logs/DiagnosticReports/调试心法
- 分而治之:先确定问题在主进程还是渲染进程
- 最小复现:移除无关代码,用最小示例复现问题
- 日志先行:在关键路径添加日志,追踪执行流程
- 版本对照:如果之前正常,用
git bisect定位引入问题的提交 - 社区资源:Electron 的 Issue Tracker 和 Discord 是宝库
B.6 DevTools 扩展与性能分析
安装 electron-devtools-installer
在 Electron 中安装 Vue DevTools 等 Chrome 扩展:
bash
npm install electron-devtools-installer --save-devjavascript
// main.js — 开发环境下自动安装 Vue DevTools
const { app } = require('electron')
const installExtension = require('electron-devtools-installer')
app.whenReady().then(() => {
installExtension.default(installExtension.VUEJS_DEVTOOLS)
.then((name) => console.log(`已安装扩展: ${name}`))
.catch((err) => console.log('扩展安装失败:', err))
})Performance 面板使用教程
DevTools 的 Performance 面板是诊断渲染卡顿的核心工具:
- 打开 DevTools → 切换到 Performance 面板
- 点击录制按钮(●),执行触发卡顿的操作
- 停止录制后分析结果:
- 火焰图中长条任务(红色三角) = 可能需要拆分的长任务(Long Tasks)
- Summary 面板 自下而上查看耗时占比
- FPS 图表 绿色 = 60fps,红色 = 掉帧
B.7 Worker Threads 调试
Worker 线程运行在独立的 V8 实例中,不能直接设置断点:
bash
# 启动时附加 Worker 调试端口
electron . --inspect=5858 --inspect-workers
# 在 Chrome 中打开 chrome://inspect 查看所有 Workerjavascript
// 在 Worker 代码中添加调试日志
const { parentPort } = require('worker_threads')
parentPort.on('message', (data) => {
console.log(`[Worker] 收到任务:`, data) // 日志会输出到主进程终端
debugger // 配合 --inspect-workers 可在此断点
})B.8 常见问题排查补充
CSP 错误排查
Refused to load the script 'xxx' because it violates the following CSP directive...排查步骤:
- 检查
index.html中的<meta http-equiv="Content-Security-Policy">标签 - 如果主进程中通过
session.webRequest注入了 CSP 头,确认规则正确 - 开发阶段可临时放宽策略:
content-security-policy: default-src 'self' 'unsafe-inline' 'unsafe-eval' - 确认所有外部资源(CDN、API)的域名已加入
connect-src白名单
打包后资源加载失败
Failed to load resource: net::ERR_FILE_NOT_FOUND常见原因:
- 使用了绝对路径而非
path.join(__dirname, '...') asar打包后__dirname行为变化- 未将静态资源纳入
extraResources
原生模块加载失败
bash
# 检查原生模块是否针对当前 Electron 版本编译
npx @electron/rebuild -f
# 检查 node_modules 中的 .node 文件
find node_modules -name "*.node" -type f
# 确认 electron-builder.yml 中配置了 asarUnpack