网易首页 > 网易号 > 正文 申请入驻

JavaScript 断点调试技巧

0
分享至

作者:陈亦涛来源:大转转FE

为什么要使用 debugger

这篇文章将介绍如何使用断点来进行 JavaScript 调试。在读这篇文章之前,需要问一个问题:为什么要使用断点来进行调试?

我们首先需要认可使用断点的是必要的,否则下文介绍的所有断点调试方法都会是废话。console.log 是前端开发最常用的调试手段,它简单直接解决一部分问题。但当遇到十分复杂的问题,console.log 就会变得不趁手。比如:

  • 一个逻辑复杂的算法

如果你刷过 leetcode 一定深有体会,算法某个测试用例报错了,有时很难光靠目测找出有问题的那个方法。

  • 一个复现步骤十分繁琐的bug。

花了10分钟好不容易复现了,但是只跟踪到某行代码,需要第二次添加 log 才能继续寻找问题。查看log -> 添加log -> 查看log... 这个过程重复几遍,今天剩下的砖就搬不完了。

  • 一段运行流程冗长的代码
  • 一段没有注释、起名随意的代码
  • server 端代码

有 nodejs 服务端开发经验的同学相信有过在 postman 和 ide 之间反复横跳的经历,如果光靠 log,对于一个巨大的复杂对象,控制台是不好查看全貌的。如果一个接口还涉及到数据库增删、第三方依赖,那么复原上一次请求造成的后果也是一件痛苦的事情。

在这些情况下,断点调试是非常有价值的,将 debug 的时间复杂度从 O(n) 降到 O(1),让搬砖更快乐。

这是文章的内容大纲:

  • Chrome debugger 基本用法
  • VS Code 调试 SPA 应用
  • Chrome 调试 Nodejs
  • VS Code 调试 Nodejs
Chrome debugger 基本用法

最简单的断点调试,就是在代码中加一句 debugger,然后到浏览器中刷新页面,这时候浏览器就会在 debugger 语句那停止执行。

为了方便理解,引入一个简单例子,在一个文件夹中创建 index.html 和 index.js,然后在 index.html 中引入 index.js。index.js 内容如下:

// 国际惯例,hello world。
const greet = () => {
const greeting = "hello debugger";
// 浏览器执行到这里将会暂停
debugger
console.log(greeting);
};
greet();
console.log("js evaluation done");

执行命令:

npm i -g serve
serve .

然后访问 http://localhost:5000并打开开发者工具。

这时候我们的 hello world 断点就打上了,就像这样:

d8090eb4-4a1f-4dfb-bf30-c08c762d66ad

图中分为四个区域,蓝色区域用于文件选择,Page 一栏是指当前页面中的 JS 文件,Filesystem 会显示我们系统中的文件。通常我们使用 Page。

粉色是代码的行号和内容。代码的行号处可以通过点击来添加新的断点,再次点击后取消。

黄色区域用于控制代码的执行,只需要掌握前四个按钮的含义,就可以应付绝大多数场景。按钮1是让代码继续执行(resume),如果遇到下一个断点就会再次中断执行。按钮2可以让浏览器执行当前行(图中是第3行),然后在下一行中断代码,按钮3是进入当前函数,查看函数具体内容。假设我们当前停在第7行 greet() ,点击按钮3就会进入 greet 方法中(也就是第2行)。如果不想再看 greet 方法了,就点击按钮4,跳出这个方法,回到第8行。

绿色区域可以查看变量的内容和当前的调用栈。

debugger 是最简单粗暴的打断点方式,但是需要修改我们的代码。需要注意的是,上线前必须删除这些语句。也可以通过配置 webpack 来自动去除。不过终究还是有些不方便,所以我们来看下如何通过 vscode 来简化打断点的方式。

VS Code 调试 SPA 应用

首先我们使用 Vite 来创建一个 Vue 应用用于演示(React步骤类似)。

# 创建 vut-ts 应用
npm init vite
cd hello-vite
npm install
# 调用 VS Code cli 打开项目,
# 或者手动在 VS Code 打开。
code .
npm run dev

然后在 VS Code 中新建一个文件 .vscode/launch.json,填入这些内容:

{
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Vue project",
// 这里填入项目的访问地址
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
},
]
}

然后使用 cmd+q 退出你正在运行的 Chrome(这步很重要,不能跳过),按 f5 启动 VS Code 的调试功能。VS Code 就会帮你启动一个 Chrome 窗口,并访问上述配置的中的 url。这时候我们的断点就生效了,可以一步一步地控制代码的运行,找出 bug 来源。

这里有一个实用的小技巧,就是在 BREAKPOINTS 中,把 Uncaught Exceptions 勾上,这样在代码报错的地方,就会自动中断执行。当我们遇到一个报错时,采用这个方法可以省去定位问题代码的时间。

另外我们可以发现,在 VS Code 断点生效时,Chrome Devtools 也会同步这个展示这个断点。

在 VS Code 中,调试有两种模式,分别是 launch 和 attach。由于真正执行代码的是 Chrome 中的 JS 引擎,所以是否中断代码的控制权是在 Chrome 手里的。那为什么 VS Code 的断点可以控制代码的中断呢?是因为 VS Code 通过 devtools-protocol 向 Chrome 发起指令,告诉 Chrome 需要在哪一行代码暂停执行。这个发送指令的过程,被称作 attach。而 launch 的过程包含 attach ,即先 launch(启动) 浏览器,然后 attach(附加) 断点信息。所以 attach 模式是 launch 模式的子集。

听起来好像 launch 模式会更方便,为我们省去了手动启动浏览器的过程。但是这存在一个问题,如果同时开发多个前端工程会怎样?每个工程启动一个调试进程,就会打开多个浏览器,那么在多个浏览器之间切换就会显得很麻烦。我们可以使用 attach 模式解决这个问题。

首先我们使用命令行启动 Chrome。使用命令行的原因是,我们需要给 Chrome 的启动传参。

# 运行这条命令前需要cmd+q退出已运行的Chrome
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# 如果看到这个输出,说明传参成功。
DevTools listening on ws://127.0.0.1:9222/devtools/browser/856a3533-ca5c-474f-a0cf-88b7ae94c75b

VS Code 和 Chrome 是通过 websocket 交流,--remote-debugging-port 指定了 websocket 使用的端口。然后我们将 launch.json 文件修改成这样:

{
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "attach",
"name": "Vue Application",
// 项目访问的 url
"url": "http://localhost:3000",
// websocket 端口,需要与 --remote-debugging-port 参数保持一致。
"port": 9222,
"webRoot": "${workspaceFolder}"
},
]
}

注意在启动 VS Code 调试之前,需要在 Chrome 中打开 http://localhost:3000 这个页面。然后我们在 VS Code 中打上断点,刷新浏览器,代码就成功停在断点处了。第二个、第n个工程都可以采用相同的配置,区别是 url 字段要根据项目配置进行修改。

Chrome 调试 Nodejs

上文讲的是如何调试页面,接下来我们聊如何调试 nodejs 应用。首先来一个最容易上手的例子,创建一个 hello world:

// debug.js 文件
const greeting = 'hello nodejs debugger'
debugger
console.log(greeting)

然后运行这个文件

node --inspect-brk debug.js
Debugger listening on ws://127.0.0.1:9229/b9a6d6bf-baaa-4ad5-8cc6-01eb69e99f0a
For help, see: https://nodejs.org/en/docs/inspector

--inspect-brk 表示运行这个 js 文件的同时,在文件的第一行打上断点。然后打开 Chrome,进入 Devtools。点击红框处的按钮,就会打开一个 nodejs 专用的调试窗口,并且代码在第一行中断了。

nodejs 调试窗口:

这个方式的实质是,Chrome Devtool 根据 v8引擎的调试协议 向 nodejs 进程发送指令,控制代码的运行。可以发现,在网页的调试中,Chrome 是接受指令的一方,而在 nodejs 调试中,Chrome 转身变为发送指令的一方。所谓从悲惨的乙方华丽转身成甲方。

node 默认的 websocket 端口是 9229,如果有需要的话(比如端口被占用了),我们可以通过一些方式改变这个端口。

node --inspect=9228 debug.js
Debugger listening on ws://127.0.0.1:9228/30f21d45-9806-47b8-8a0b-5fb97cf8bb87
For help, see: https://nodejs.org/en/docs/inspector

在我们打开 Devtool 时,Chrome 默认检查 9229 端口,但当我们改变了端口号后,就需要手动去指定 Chrome 检查的地址了。点击下图中的 Configure 按钮,输入 127.0.0.1:9228,然后点击 Done。这时候 Remote Target 中就会出现 刚才启动的 node 进程,点击 inspect 就可以进入调试了。

使用 VS Code 调试 Nodejs

到此为止,我们已经达成调试 node 的目的,但还有些繁琐,不够自动化。我们可以使用 VS Code,来一键启动调试。

用 VS Code 打开刚才的工程,然后在 launch.json 中输入这些:

{
"version": "0.2.0",
"configurations": [
{
"type": "pwa-node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"

/**" ], // ${file} 的意思是,当我们启动调试的时候,调试的程序就是当前 focus 的文件。 "program": "${file}" } ] }

这时候切换到 index.js 文件,按 f5 启动调试程序,当运行到第二行 debugger 语句的时候,就会自动暂停执行。也可以点击代码行数的左侧来打断点。

另外,这个配置是支持 TypeScript 的,我们只需要 index.js 重命名为 index.ts,然后正常启动调试就行。

Conditional Breakpoint 条件断点

在某些情况下,我们不希望打上的每个断点都发挥作用,而是在执行到断点那行,且满足某个条件再中断代码执行。这就是条件断点。

for (let i = 0; i < 10; i++) {
console.log("i", i);
}

比如上面的代码,假设我们在第二行 console.log 打了断点,那么这个断点总计会中断十次。这往往是我们不希望看到的,可能我们需要的仅仅是其中某一次循环而非所有。这时候可以右键点击并选择 Add Conditional Breakpoint。

这时会有一个输入框出现,我们在其中输入 i === 5。

这时候启动调试,就会跳过 i 为 0 - 4,直接在在 i 为 5 的时候中断代码执行。恢复代码执行后,会略过 i 为 6 - 9 的情况。

Conditional Breakpoint 在调试带有大量循环和 if else 判断时极为有用,特别是当某处的逻辑整体上是符合预期的,仅有个别特殊情况的输出错误,使用条件断点就可以略过这些正常的情况,只在个别特殊情况出现的时候,再中断执行,供我们查看各个变量是否计算正常。

总结

调试是日常工作中非常重要的能力,因为除了开发新功能外,日常有很大一部分都在调整旧的代码,处理特别条件下的逻辑错误。熟练掌握调试可以很好地提升搬砖幸福感,一个复杂的 bug 卡几小时,很容易让人心里崩溃。但也不是说断点调试是任何情况下都适用的银弹,简单的逻辑还是可以愉快地 console.log 的。

文章介绍了使用 Chrome Devtools 和 VS Code 断点调试的方法,整体上还是更推荐使用 VS Code。launch.json 只需要一次配置,后续都可以 f5 一键启动调试。另外,文中提到的各种 launch.json 文件的配置,都可以使用 VS Code 自带的工具一键生成。只要打开 launch.json,编辑器的右下角就会出现 Add Configuration 按钮,点击就可以选择自己需要添加的调试配置。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
死缓!刘连舸,收受贿赂后为多人谋取职务提拔、调整

死缓!刘连舸,收受贿赂后为多人谋取职务提拔、调整

政知新媒体
2024-11-26 17:39:23
收钱1.21亿、违法放贷33.2亿,刘连舸被判死刑

收钱1.21亿、违法放贷33.2亿,刘连舸被判死刑

新动察
2024-11-26 17:54:57
亚冠东亚区积分榜:泰山海港赢球进入前八,申花明日战光州

亚冠东亚区积分榜:泰山海港赢球进入前八,申花明日战光州

懂球帝
2024-11-26 22:22:06
曝武汉大学国际文化节上,中华展区选择清朝服饰!网友:韩国人看到能笑死

曝武汉大学国际文化节上,中华展区选择清朝服饰!网友:韩国人看到能笑死

可达鸭面面观
2024-11-26 22:07:56
16岁到93岁!老太独坐江边等丈夫77年,哭瞎一只眼,终于了结遗憾

16岁到93岁!老太独坐江边等丈夫77年,哭瞎一只眼,终于了结遗憾

历史看小流
2024-11-15 15:44:08
建议老胡不要再给“各方”提建议了

建议老胡不要再给“各方”提建议了

近距离
2024-11-26 16:05:50
乌军果然大规模袭击罗斯托夫!英国送来数十枚风暴阴影导弹

乌军果然大规模袭击罗斯托夫!英国送来数十枚风暴阴影导弹

项鹏飞
2024-11-26 20:05:01
韩军方:朝军切断韩朝输电塔电线

韩军方:朝军切断韩朝输电塔电线

上观新闻
2024-11-26 13:35:08
网传某知名寺庙的住持带领僧人申请美国签证,仅四五位弟子过关,四十多人被拒

网传某知名寺庙的住持带领僧人申请美国签证,仅四五位弟子过关,四十多人被拒

六子吃凉粉
2024-11-26 21:50:07
肇庆一殡仪馆被曝用炖盅当骨灰瓮,民政局:余者已弃用,将整改

肇庆一殡仪馆被曝用炖盅当骨灰瓮,民政局:余者已弃用,将整改

极目新闻
2024-11-26 19:20:44
某顶级建筑央企全线大崩溃:领导层绩效砍半

某顶级建筑央企全线大崩溃:领导层绩效砍半

黯泉
2024-11-26 21:33:06
广西钟山妇联通报“一没有妈妈的小女孩经常坐在光棍男子怀里”

广西钟山妇联通报“一没有妈妈的小女孩经常坐在光棍男子怀里”

环球网资讯
2024-11-26 20:24:13
曝大批网友给殴打霸凌学生的王所长送锦旗,市局领导怕影响太大,不让拍视频

曝大批网友给殴打霸凌学生的王所长送锦旗,市局领导怕影响太大,不让拍视频

可达鸭面面观
2024-11-26 08:36:58
红四方上市首日盘中暴涨2200%!“四方”上市公司都跟着“喝汤”

红四方上市首日盘中暴涨2200%!“四方”上市公司都跟着“喝汤”

第一财经资讯
2024-11-26 20:20:01
39岁科学家被举报诈骗10几亿!本人常上新闻,妻子被捕,细节曝光

39岁科学家被举报诈骗10几亿!本人常上新闻,妻子被捕,细节曝光

林大师热点
2024-11-26 16:04:05
放假通知,2025中小学寒假放假时间确定了,家长却表示难以接受

放假通知,2025中小学寒假放假时间确定了,家长却表示难以接受

男女那点事儿儿
2024-11-26 20:46:23
下辈子当狗比当人强!曝一位工地阿姨的话道出现实:种500年地也买不了房子

下辈子当狗比当人强!曝一位工地阿姨的话道出现实:种500年地也买不了房子

可达鸭面面观
2024-11-26 23:04:14
河南一患者花120万打一针抗癌药,1个月后癌细胞消失五分之四:这药真贵,但能救命

河南一患者花120万打一针抗癌药,1个月后癌细胞消失五分之四:这药真贵,但能救命

保险课堂
2024-11-26 23:17:02
普京告诉特朗普,就算不用核弹你也会输,中国已出手卡住老美脖子

普京告诉特朗普,就算不用核弹你也会输,中国已出手卡住老美脖子

闫树军论评
2024-11-25 09:10:17
马斯克嘲笑“傻子还在生产F-35战机”,称无人机才是趋势 军事专家:他思路有问题

马斯克嘲笑“傻子还在生产F-35战机”,称无人机才是趋势 军事专家:他思路有问题

红星新闻
2024-11-26 16:53:12
2024-11-27 05:39:00

科技要闻

"这是国产化最高,也是史上最强的Mate"

头条要闻

墨西哥总统称墨不是中国产品转口美国的途径 中方回应

头条要闻

墨西哥总统称墨不是中国产品转口美国的途径 中方回应

体育要闻

勒沃库森3分钟两球!维尔茨点射、格里马尔多任意球破门

娱乐要闻

权威奖项沦为资本工具?谁来管一管

财经要闻

洪灏刘煜辉对谈实录 涉及A股、债务等!

汽车要闻

解决油车无法处理的难题 仰望U7数字底盘这么强

态度原创

艺术
手机
本地
数码
公开课

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

手机要闻

iPhone 16摄像头表现远不及16 Pro机型 在DXOMARK的测试中排名第20位

本地新闻

城市24小时|领跑万亿城市,武汉“开挂”了?

数码要闻

Yeelight 易来推出智能开关 T2:白瓷青墨双色,144 元起

公开课

一块玻璃,如何改变人类世界?

无障碍浏览 进入关怀版