写点什么

前端调试实践

  • 2024-12-03
    北京
  • 本文字数:4145 字

    阅读完需:约 14 分钟

前端调试实践

作者:效能研发部 黄泽平

前言

在日常调试问题中,相信我们很多人都是用 console 去排查相关的问题,虽然问题也可以排查出来,但是有时它的效率并不高。这篇文章主要讲解关于断点和一些日常调试技巧的内容,方便你在日后调试问题中,能在不同的前端场景应用不同的调试方式,翻倍提高你解决问题的效率



1 sources 面板概览

source 面板是我们断点调试经常用的到的地方,我们可以先大概认识一下它长什么样子,大概有什么功能



•左侧区块:包含了 Page、Overrides、Snippets 等 5 个功能块,其中 Page 可以查看该网页已加载的所有资源

•中间区块:可查看、编辑资源文件,也可查看图片类型的文件;同时可在其文件左侧进行断点等相关操作

•右侧区块:断点调试时的区域,可以开始、下一步等断点操作,同时可以查看断点调试时的变量值、调用栈等信息



点击并拖拽以移动

编辑



当展示开发者工具的区域过小时,它会自适应调整布局



点击并拖拽以移动

编辑



2 常用的断点方式

我们平常最经常用的可能就是代码行断点了,但是有时用它调试问题并不是效率最高的。chrome 中还包含了其他的断点方式,我们可以在不同的场景应用不同的断点进行高效调试。



2.1 代码行断点

代码行断点,当代码运行到当前行之前,代码会暂停执行



2.2.1 点击 Sources 面板中的源代码的行号

当行号列对应行出现蓝色图标,即为打断点成功。在右侧的 Breakpoints 中,会出现你有打断点的信息,展示了对应的行号,也可以让你取消、勾选、编辑、删除断点



点击并拖拽以移动

编辑



2.2.2 断点操作按钮含义

我们可以在右上角看到 6 个控制断点的操作按钮,分别对应着不同的操作



点击并拖拽以移动

编辑



点击并拖拽以移动

编辑



恢复执行



点击并拖拽以移动

编辑



单步执行



点击并拖拽以移动

编辑



进入函数调用



点击并拖拽以移动

编辑



跳出函数调用



点击并拖拽以移动

编辑



让该断点失效



2.2.3 行断点实战

在开发过程中,用例列表刚开始还可以加载出用例,怎么突然没有数据返回了。查看接口发现 moduleIds 参数出现了问题



点击并拖拽以移动

编辑



于是对相关代码行设置了断点,当执行到 149 行的时候 moduleIds 的值是 [4611,5417]



点击并拖拽以移动

编辑



可当执行到 152 行的时候,moduleIds 的值却是 [undefined]



点击并拖拽以移动

编辑



原来是这两处逻辑冲突了,后面的逻辑覆盖了前面的逻辑



点击并拖拽以移动

编辑



问题很快排查出来。如果用 console.log 的话,可能要在代码中写好几个 console,保存后,刷新浏览器打印,排查完,可能还需要去删除掉,所以遇到一些问题排查效率就提高了许多



2.2 Logpoint 日志点

有时候,我们并不需要像代码行断点一样,把我们的代码暂停。我们只需要像 console 打印一下相关的信息,不要中断我们的代码执行。这个时候我们 logpoint 就派上用场了,它的语法跟 console.log 一样,我们可以快速得写好我们的调试信息,而且不用像 console.log 一样干扰我们的代码,也不用过后还得惦记着去删除它



比如下面的 logpoint,其会显示粉红色的图标,代码执行到它的时候,它会在 console 面板中打印



点击并拖拽以移动

编辑



注意,我们可以使用点击 esc 快捷键,快速得调起我们的 console 面板查看信息



点击并拖拽以移动

编辑



2.3 异常断点

当我们的代码有错误,引发对应的异常报错时,我们有时会比较难快速定位到是在哪里出现了问题。我们可以利用异常断点,在发生异常的时候立即进行断点,从而快速找到发生问题的代码,并且可查看相关的变量、调用栈来帮助我们排查问题。



异常断点分为两种,可分别在在未捕获和已捕获的异常处进行断点



2.3.1 Pause on uncaught exceptions

比如下方代码中,aa 要访问一个不存在的变量,这里是有问题的。这也是我们在代码中经常会遇到的问题

  const handleClick = () => {    const aa = null;    const bb = aa.size;    setIsClicked(true);  };

复制代码


点击并拖拽以移动



我们可以在 Breakpoints 中勾选 Pause on uncaught exceptions,当代码执行到这些有异常的代码时,自然会暂停



点击并拖拽以移动

编辑



点击并拖拽以移动

编辑



2.3.2 Pause on caught exceptions

下方代码已经异常进行了捕获,这种情况可以勾选 Pause on caught exceptions 来对捕获到异常代码行暂停进行处理

  const handleClick = () => {    try {      const aa = null;      const bb = aa.size;      setIsClicked(true);    } catch (error) {      console.error("1-zp-error:", error);    }      };

复制代码


点击并拖拽以移动



点击并拖拽以移动

编辑



2.4 事件监听器断点

当用户发生交互时出现问题,这时我们就可以添加事件监听器添加断点来捕获这些事件以检查交互时的问题。可以在 Source 面板右侧的 Event Listener Breakpoints 中勾选相应的事件



点击并拖拽以移动

编辑



2.5 DOM 更改断点

使用频率不高,研究如何操作 dom 的特定场景才有有用



点击并拖拽以移动

编辑



3 调用栈

当我们在查看、调试一段比较复杂的代码时,我们有时很难快速得从代码文件理清其调用关系。此时,我们可以利用调用栈来帮助我们快速理清逻辑,快速排查问题



3.1 栈

栈是一种数据结构,其内部的的元素满足后进先出的特点,我们可以对其进行入栈、出栈的操作



点击并拖拽以移动

编辑



3.2 调用栈的应用

比如我在 caseReviewListTable 文件的第 206 行代码中打了一个断点,当代码执行到这部分逻辑的时候,他就自然会暂停



点击并拖拽以移动

编辑



我们此时可以看到右侧的 Call Stack 中从上到下排列着函数调用栈信息,如下图我们可以查看到,在执行到该断点的时候,我们已经先在其他文件的 handleRefreshCaseReviewList、handleSearchCase 函数中执行过相关代码了。我们可以点击函数名右侧的文件地址,快速查看对应的代码,这样子,我们对其调用逻辑清晰了许多,排查问题的效率自然会提高



点击并拖拽以移动

编辑



3.3 anonymous 匿名的

我们在看上面的代码中,发现有一个 anonymous 栈帧,他代表了是一个匿名函数,即没有名称的函数



点击并拖拽以移动

编辑



比如下面代码我们加个 setTimeout,也会在调用栈生成一个 anonymous 的栈帧



点击并拖拽以移动

编辑



3.4 console.trace()

除了通过断点来查看调用栈,有时我们也使用 console.trace() 来输出当前的函数调用关系,比如我们在下面代码对应的位置加上 console.trace(),我们就可以看到其当前位置的调用栈信息



点击并拖拽以移动

编辑



4 Snippets

在浏览器中,如果你在调试中,有一些公共的逻辑需要经常用到,你可以把其代码片段保存在 Snippets 中。当你在任何一个页面需要运行它的时候,可以直接运行它



比如我们想要获取当前页面的所有图片链接,我们可以将这段代码存储起来



点击并拖拽以移动

编辑



需要用的时候,我们直接快捷键 Command+P,输入!字符,搜索你要执行的代码片段名称,选择以后即可执行



点击并拖拽以移动

编辑



5 Overrides

5.1 替换响应内容

如果有些异常数据导致页面发生问题,我们可以直接利用那份异常数据,在本地进行调试。当然,如果后端接口还没好,我们知道结构也可以 mock 数据



比如我们现在有一个/api/v2/review/list/getCaseReviewList 接口



点击并拖拽以移动

编辑



我们右键,选择 Override content 替换接口内容



点击并拖拽以移动

编辑



选择以后,会需要你选择一个存储这些替换文件的文件夹



点击并拖拽以移动

编辑



授权



点击并拖拽以移动

编辑



我们将我们的模拟数据填充在这里,即可在页面中调试我们的 UI 和相关逻辑了



点击并拖拽以移动

编辑



其中,被覆盖的接口会显示紫色的标识



点击并拖拽以移动

编辑



如果我们不需要了,根据情况禁止、删除、清空都可以



点击并拖拽以移动

编辑



5.2 替换响应头

如果有些场景,需要添加或者修改响应头,也可以进行自定义修改



点击并拖拽以移动

编辑



选择 Add header,然后自己添加修改对应的响应头数据



点击并拖拽以移动

编辑



6 其他调试技巧

6.1 复制、粘贴、拖拽元素

当产品需要对已经开发好的页面进行一些位置的移动调整的时候,我们可能对代码有一个比较大的改动才可以给她看到效果,但是过后我们又得把代码改回去。这时,我们可以利用 chrome 提供给我们的能力,复制元素、粘贴以及拖拽元素,来实现快速的页面布局调整,给产品看到效果,又不需要改代码



比如我们复制今日工作这个区块,然后粘贴在你需要放置的位置容器下进行粘贴



点击并拖拽以移动

编辑



粘贴以后,我们长按元素,进行拖拽调整位置即可



点击并拖拽以移动

编辑



6.2 全局搜索

6.2.1 全局搜索文件/目录

当我们要快速调试一个文件的代码的时候,直接按 Command+P 快捷键调起搜索浮层,输入文件名或者文件路径名,即可快速找到对应的文件,选择点击以后会到达 sources 面板打开对应的文件



点击并拖拽以移动

编辑



6.2.2 全局搜索代码

当我们有对应的代码关键词,想打开它对应的文件。chrome 提拱了一个全局搜索代码的功能,我们可以打开对应的 search 面板



点击并拖拽以移动

编辑



比如我输入“name: '计划列表',”这个关键词,它会在这个页面已经引入的资源搜索对应的代码关键词,然后把匹配的文件展示在下方,我们就可以立即选择然后打开对应的代码文件了



点击并拖拽以移动

编辑



6.3 网站样式风格概览 CSS Overview

当我们看到一些优秀的网站的时候,我们想快速查看借鉴该网站样式信息的时候,我们可以借助 CSS Overview 这个功能快速得到相关信息,非常好用有趣



比如我们拿花瓣这个网站做例子,我们打开开发者工具,开启 CSS Overview 面板



点击并拖拽以移动

编辑



然后按“Capture overview”开始收集信息



点击并拖拽以移动

编辑



收集好以后,我们便可以从颜色、字体等维度获取到该网站的样式信息



点击并拖拽以移动

编辑



另外,当我们点击对应的色块的时候,它也会列出用到的地方,点击对应的元素也会快速定位过去



点击并拖拽以移动

编辑



6.4 折叠屏手机适配

如果我们的开发场景中,需要适配折叠屏手机,比如像下面的三星 Galaxy Z Fold5,那么我们的 chrome 也可以派上用场



点击并拖拽以移动

编辑



三星 Galaxy Z Fold5



我们需要进入对应的移动端调试模式,选择对应的移动端设备



点击并拖拽以移动

编辑



选择折叠场景,然后我们即可进行调试了



点击并拖拽以移动

编辑



调试 Surface Duo 设备



点击并拖拽以移动

编辑



点击并拖拽以移动

编辑



7 学习资源分享

前面讲了这么多,其实只是抛砖引玉,还有很多东西是我们没有讲到的,我们可以通过下面的渠道进一步的了解、应用相关的知识和工具



7.1 Chrome DevTools

包含了 Chrome 开发者工具相关功能的详细介绍还有相关的实践应用场景



7.2 Google Chrome Developers - YouTube

Google Chrome Developers 的 YouTube 频道,视频展示了相关的新功能以及最佳实践



7.3 浏览器工作原理与实践

极客时间这门课从浏览器的渲染、javascript 执行机制、V8 工作原理、安全等相关视角去讲解浏览器的相关内容,从而让我们对前端的体系有一个更全的理解



8 总结

本文介绍了断点调试、sources 面板和日常使用到的一些调试技巧,帮助我们在后续的开发中,提供一些新角度、新方式来解决问题,翻倍提高我们的开发效率

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2024-01-12 加入

京东零售那些事,有品、有调又有料的研发资讯,带你深入了解程序猿的生活和工作。

评论

发布
暂无评论
前端调试实践_前端_京东零售技术_InfoQ写作社区