3、Sources面板实战:断点调试、单步执行、调用堆栈、作用域查看
调试,说白了就是给代码看病。你写了一大堆逻辑,运行时却出了幺蛾子,怎么办?
我个人习惯,第一反应就是打开 Sources 面板。这玩意儿是 Electron 调试的核心阵地,比 console.log 大法不知道高到哪里去了。
3.1 断点调试:让代码停下来等你
断点调试,就是告诉 V8 引擎:「嘿,执行到这一行的时候,先停一下,让我看看情况。」
怎么加断点?简单得很。打开 Sources 面板,找到你要调试的 JS 文件,在行号上点一下,就会出现一个蓝色箭头。这就是断点。
举个例子,假设你有这么一段代码:
// renderer.js
const { ipcRenderer } = require('electron')
document.getElementById('btn').addEventListener('click', () => {
const data = collectFormData()
// 在这里打个断点
ipcRenderer.send('save-data', data)
})
ipcRenderer.on('data-saved', (event, result) => {
// 在这里也打个断点
updateUI(result)
})
我在项目中遇到过一个问题:点击按钮后界面没反应。我在 ipcRenderer.send 那行打了断点,发现数据根本没发出去。再往前查,原来是 collectFormData 函数里有个空指针异常。你看,断点一打,问题立马现形。
3.2 单步执行:一步一步看代码怎么跑
断点停住后,怎么继续?这时候就要用单步执行了。
Sources 面板顶部有一排控制按钮,我常用的有这几个:
| 按钮 | 快捷键 | 作用 |
|---|---|---|
| ▶ 继续执行 | F8 | 直接跑到下一个断点 |
| ↘ 单步跳过 | F10 | 执行当前行,不进入函数内部 |
| ↗ 单步进入 | F11 | 执行当前行,如果遇到函数就跳进去 |
| ↖ 单步跳出 | Shift+F11 | 执行完当前函数剩余代码,跳回调用处 |
嗯,这里要注意:如果你只是想看当前函数逻辑,用 F10 就够了。但如果你怀疑某个函数内部有问题,那就用 F11 钻进去看看。
我曾经调试一个 Electron 主进程的 IPC 处理函数,发现数据格式不对。用 F11 一步步走进处理函数,才发现里面有个 JSON.parse 抛了异常,但被一个空的 try/catch 给吞掉了。这种问题,不单步执行根本看不出来。
3.3 调用堆栈:谁调了谁?
代码停住后,右侧的 Call Stack 面板会显示当前函数的调用链。说白了,就是「谁叫了谁,一路叫到这儿」。
举个例子,你停在一个深层函数里,Call Stack 从上到下依次显示:
saveToDatabase(当前停在这里)processData(调用了 saveToDatabase)handleSave(调用了 processData)onclick(调用了 handleSave)
点击任意一行,就能跳到对应的代码位置。这个功能在排查「为什么这个函数会被调用」时特别有用。
anonymous 或者 eval,说明你的代码可能用了动态执行或者回调地狱。这时候建议先重构代码,再调试。
我记得有一次,Electron 的渲染进程莫名其妙地调用了某个函数。我打了断点,一看 Call Stack,发现是某个事件监听器触发的。再往上查,原来是事件绑定时传错了参数。Call Stack 就像一张地图,帮你把调用路线画得清清楚楚。
3.3 作用域查看:变量值一目了然
代码停住后,右侧的 Scope 面板会显示当前作用域下的所有变量。分为三类:
- Local:当前函数的局部变量
- Closure:闭包捕获的变量
- Global:全局变量(比如
window、document)
你可以展开每个变量,查看它的值、类型、甚至对象的内部属性。更厉害的是,你还可以直接在 Scope 面板里修改变量的值!
比如你调试时发现 user.name 是 undefined,你可以双击它,改成 'test',然后继续执行。这样就能测试「如果数据正常,后续逻辑会不会出问题」。
process 对象。比如 process.versions 能看到 Electron、Node、Chrome 的版本号,process.argv 能看到启动参数。这些信息对排查环境问题很有帮助。
为什么会这样?因为 Electron 的渲染进程其实就是一个 Chrome 浏览器窗口,Sources 面板的调试能力跟 Chrome DevTools 完全一致。你想想看,你在浏览器里怎么调试网页,在 Electron 里就怎么调试。
最后说一句:调试不是万能的,但不会调试是万万不能的。我见过太多人遇到 bug 就疯狂加 console.log,然后刷新页面看控制台。其实用 Sources 面板,几分钟就能定位的问题,console.log 可能要折腾半小时。
嗯,这一章的内容就到这里。下一章我们会聊聊 Network 面板,看看怎么抓 Electron 的网络请求。到时候你会发现,很多「诡异」的问题,其实都是网络请求搞的鬼。