前端调试的最佳实践

发表于 2年以前  | 总阅读数:400 次

一、背景

作为前端工程师,无论是开发还是线上环境,浏览器或是 node,移动端或者 PC 端,经常会遇到一些 bug,那么如何快速定位和解决问题呢,笔者准备了一份前端调试指南供大家参考。

「文章大纲」

调试本身可以分为两个过程,「定位问题」「解决问题」。而更重要的显然是如何快速的定位问题。本文将集中讨论如何 「快速发现」「调试问题」,至于如何解决问题,那就是开发本身的事情,无法一概而论了。

二、调试工具方法

2.1 Chrome DevTools 的使用

Chrome 的 DevTools 是最常用的调试工具,下面主要介绍下 「Elements」「Console」「Source」 三个面板的使用。

2.1.1 Elements

Elements 面板会显示目前网页中的 DOM、CSS 状态,且可以修改页面上的 DOM 和 CSS,即时看到结果,省去了在编辑器修改、储存、浏览器查看结果的流程。

Elements 主要可以分为 DOM 结构以及元素(Element)内容两个子面板,下面主要介绍一下 Elements DOM

$n

开启 Elements 面板时,标记的元素后方总会有个 == $0

image-20220116212438893

选中一个元素后再到 Console 面板输入$0,会发现刚刚选中的元素出现在 Console 中,如果再多点几个元素,还可以用$1$2$3$4(到此为止)来拿到前几次选到的元素。

另外在 Console 中对元素按下右键,选择 Reveal in Elements Panel 可以跳到该元素在 Elements 面板中的位置,对 Elements 面板的元素按下右键则有 Scroll to view 可以把视野滚到能看见元素的地方。

想要在 Console 面板中用 JavaScript 操作元素时,$0就非常方便,另外也可以搭配 console.dir($0) 来观察元素的各个属性,如果在 Console 直接输入 $0 或是 console.log($0) 只会显示元素自身。

image-20220116212412476

inspect

有时候一些 dom 节点会嵌套很深,导致我们很难利用 Element 面板 html 代码来找到对应的节点。inspect(dom元素)可以让我们快速跳转到对应的 dom 节点的 html 代码上。 eg:在 console 输入inspect($('#app')),回车后便可以跳转到#app 节点的 html,进行审查元素

2.1.2 Console

Console 面板作为 shell 提示窗口用来和页面文档以及 DevTools 进行交互

console 对象

前端说起调试,最常用的肯定就是console.log方法,但是 console 是一个对象,上面还有很方便的方法。

console.table() 可用于打印 obj/arr 成表格

image-20220104154752095

console.trace() 可用于 debugger 堆栈调试,方便查看代码的执行逻辑,也可以帮助我们看一些库的源码

image-20220104155335803

console.count会印出这个标签被执行了几次,预设值是default,可以用在快速的计数。

console.countResetcount 配套,用来重置,可用在计算单次行为的触发的计数。

console.group() / console.groupEnd();

为了在一大堆混乱的讯息中一眼看到自己的 log, 通常会这样做

console.log("----start-----");
console.log(object);
console.log("---end---");

虽然 --- 是很显眼没错,但其实有更好的做法,用console.group 可以自订 Message group 的标签也可以多层嵌套,并用 console.groupEnd 来关闭 Group

console.log("iteration");
for (var firstLevel = 0; firstLevel < 2; firstLevel++) {
  console.group("First level: ", firstLevel);
  for (var secondLevel = 0; secondLevel < 2; secondLevel++) {
    console.group("Second level: ", secondLevel);
    for (var thirdLevel = 0; thirdLevel < 2; thirdLevel++) {
      console.log("This is third level number: ", thirdLevel);
    }
    console.groupEnd();
  }
  console.groupEnd();
}

$$(select)方法

$(select) 拿到的是 NodeList(伪数组),而 $$(select) 拿到的则是一个纯正的数组,方便我们在控制台上调试 API,只有在 devtools 下打印才能使用

image-20220104155823831

2.1.3 Source

Sources面板可以查看浏览器页面中的源文件(html/js/img/css等),点击面板下方的{}大括号可以将代码转成可读格式,同时可给js文件添加上断点。Sources下的Snippets可以添加文件片段,可在浏览器中运行

Breakpoints

「debugger 语句」

在代码中加上debugger语句,是仅次于console.log的常用调试方式,在需要的地方进行添加断点

chrome devtool breakpoint 下面列举一些平常使用较多的断点方式

  • 普通断点:在想断住的那一行左侧单击一下就可以添加一个断点,运行到该处就会断住。

    image-20220104161116371

  • 条件断点:右键单击代码所在的行左侧,会出现一个下拉框,可以添加一个条件断点。输入条件表达式,当运行到这一行代码并且表达式的值为真时就会断住。

image-20220104161315275

  • DOM 断点:在 Chrome Devtools 的 Elements 面板的对应元素上右键,选择 break on,可以添加一个 dom 断点,也就是当子树有变动、属性有变动、节点移除这三种情况的时候会断住。可以用来调试导致 dom 变化的代码。

image-20220104161458483

  • Event Listeners 打断点:在 Chrome Devtools 的 Elements 面板上找到你想排查的 dom 节点,右侧面板 Event Listeners 中会有当前阶节点,可以当前节点打断点调试。

    image-20220104161916972

  • 异常断点:在 Debugger 面板勾选 Uncaught Exceptions 和 Caught Exceptions 可以添加异常断点,在抛出异常未被捕获或者被捕获时断住。用来调试一些发生异常的代码时很有用。

  • Event Listener 断点:在 Chrome Devtools 的 Sources 面板还可以添加 Event Listener 的断点,指定当发生什么事件时断住,可以用来调试事件相关代码。比如拖拽事件、媒体事件断点

  • Function 在 Console 面板中可以用 debug 相当于在该 function 的第一行插入debugger
function a() {
  console.log(1);
}
// 在Console中输入
debug(a);
a();

// 相当于
function a() {
  debugger;
  console.log(1);
}
// 使用 undebug 解除
BlackBox

“BlackBox Script”可以在调试中忽略某些脚本(此处的 BlackBox 为动词),在 Call Stack 堆栈中会将该脚本隐藏,单步调试时也不会步入脚本中的任何函数。如果确认第三方库没有 bug,就可以 BlackBox 整个第三方库的 js 脚本,在调试中跳过这些代码的执行。

三种添加 BlackBox 的方法:

  1. 在源代码窗格右键,选择"BlackBox Script"
  2. 在 Call Stack 中右键某一帧,选择"BlackBox Script"
  3. 在设置中的 Blackboxing 面板添加「正则表达式」匹配「文件名」
Workspace
chrome 中「使用本地 sourceMap 调试」

第一步:打开 Filesystem add folder to workspace,把包含 sourceMap 的目录添加进去

image-20220104171549241

第二步:打开指定的混淆代码

image-20220104171821907

第三步:右键 -> 选择【Add source map】

第四步:拷贝 Filesystem 中的 sourceMap 地址。

在 chrome 中修改代码并调试

chrome devTools 提供了 local overrides 能力,首先,打开 sources 下的 overrides 面板;

然后,点击【select folder for overrides】选择修改后的文件存储地址;

image-20220104172628695

再然后,点击顶部的授权,确认同意;

最后,找到入口文件,然后右键选择 Save for overrides (一定要是原件,formatted 后的版本不行),

image-20220104173000023

然后找到保存的文件进行修改,重新刷新页面后,修改后的代码就可以被执行了。

2.2 nodejs 调试

Nodejs 使用 Chrome DevTools 调试 --inspect-brk

下面以调试 webpack 源码为例:

node --inspect --inspect-brk node_modules/webpack/bin/webpack.js --env.production --config webpack-common.js

执行 bin 中相应「启动文件」webpack.js 打开 chrome 的开发者工具页面,如果看到 node 的「绿色图标」,点击就可进入调试。

img

2.3 移动端调试 VConsole 与 eruda

whistle 配合 VConsole 或者 eruda,可以在任何环境下开启调试模式,在 whistle 中 规则中配置相应域名下进行调试,以 m.zhuanzhuan.com 域名为例

m.zhuanzhuan.com jsAppend://{eruda.js} jsAppend://{erudaInit.js}

下载 eruda.js,把 eruda.js 和 erudaInit.js 配置在 values 中

image-20220104164430460

image-20220104164328168

这样就会在移动端开启调试 eruda 模式了。

2.4 微信 WebView 调试

微信调试网页,正常来说你可以使用微信开发者工具[1] 进行调试。它本质上和 chrome://inspect 方法类似,只是它为线上的微信包提供了 debug 模式,并将操作简单化。具体的使用方法可以参考官方文档:https://x5.tencent.com/tbs/guide/debug/season1.html

2.5 Android Chrome 真机调试

如果你需要调试的 Android 手机版本 >= 4.4,则推荐使用 chrome://inspect 的方式进行调试,它能为 WebView 带来原生的开发者工具,可以方便的对代码进行断点调试。该方法需要满足以下三个条件才能使用:

  1. Android 4.4+
  2. 手机上开启允许 USB 连接设备进行调试
  3. 客户端开启 WebView debug 模式
//开启 webview 的 debug 模式
webview.setWebContentsDebuggingEnabled(true);

当满足以上要求之后,访问 chrome://inspect,页面将显示您的设备上已启用调试的 WebView 列表。要开始调试,请点击您想要调试的 WebView 下方的 inspect。像使用远程浏览器标签一样使用开发者工具。

2.6 iOS Safari 真机调试

如果你手机上安装的是 DEBUG 版应用,那么推荐使用 Safari 来调试,它能为 WebView 带来原生的开发者工具,可以方便的对代码进行断点调试。该方法需要满足以下三个条件才能使用:

  1. Mac: Safari -> 偏好设置 -> 高级 -> 在菜单栏中显示“开发”菜单勾选
  2. iOS: 设置 -> Safari -> 高级 -> Web 检查器打开
  3. 最重要的是 App 必须开启 DEBUG 模式

由于 iOS 有签名校验机制,真机正式包不允许 Safari Debug,所以安装在真机上的包必须是测试签名打的包。需要联系客户端将我们 iOS 设备的 ID 写入到可信任设备列表中,然后使用 iTunes 安装客户端提供的测试包即可。当满足以上要求后,就可以在 Safari -> 开发中看到自己的设备以及 WebView 中网页,点击后即可开启对应页面的 Inspector,可以用来进行断点调试。

2.7 weinre 调试

当系统版本或者未开启 debug 模式导致上面的方法不可用时,可以考虑使用 weinre[2]。weinre 通过在页面中插入一段脚本,将页面的所有行为发送到服务上。首先我们需要安装并启动服务:

npm install -g weinre
weinre --httpPort 8000

访问 http://localhost:8000 按照页面提示将 debug 脚本插入到页面中。访问页面后就会发现 winere 页面中出现了对应的请求记录,点击该记录即可跳到如下页面。可以看到这个就是一个网页版的开发者工具,可以方便的查看网络请求,控制台执行代码以及样式修改等。

三、调试方法汇总

方式 优点 优点 推荐场景
移动端网络代理+whistle 本地代理 移动端网络代理+whistle 本地代理 1、无法断点调试 1、推荐开发环境使用
whistle 外部工具注入(vConsole.js 或 Eruda.js) 1、方便 2、无法断点调试 1、推荐任何环境调试
Android 真机调试 1、最接近真实环境,可以断点调试 1、条件苛刻麻烦; 2、仅限 Android; 3、不够方便 1、实在找不到问题的保底手段
iOS Safari 真机调试 1、最接近真实环境,可以断点调试 1、条件苛刻麻烦; 2、仅限 ios; 3、不够方便 1、实在找不到问题的保底手段
微信开发者工具调试 1、可以 pc 一样方便的断点调试 1、仅限微信; 2、要提前将自己的账号加入到开发者账号中 1、任何需要使用到微信的场景
weinre(web inspector remote) 1、在 whistle 内有继承,比较方便; 2、方便调试样式,选中即可得 1、无法断点调试 1、任何需要调试样式的场景

四、调试一般步骤

当出现异常时,按照这个基本逻辑排查,一般可以快速定位问题。

4.1 检查控制台是否报错

可以快速确定页面不符合预期的原因

  • 是何种错误
  • 当前页面是否需要请求获取数据

4.2 是何种错误

  • 安全错误:与后端协商解决
  • SyntaxError/ReferenceError/TypeError :编译阶段一般不会放过太低级的书写错误,可以认为这类错误都是写错了 ,一般很容易发现,找到错误堆栈进行解决
  • 数据不符合预期引起的错误(TypeError 等):访问不存在的属性得到了undefined/null/NaN等值之后,会引发后续的异常。要先从检查数据入手。

4.3 当前页面是否需要请求获取数据

网络请求是不稳定因素之一,可能会带来难以预料的复杂情况,出现问题的时候检查网络请求和数据的优先级很高。

4.4. 网络请求是否成功发送

检查开发者工具 Network/网络面板,查看需要获取数据的接口是否成功获取到数据。

取不到数据的原因有两类,一类是责任在前端,一类是后端。主要通过请求提交的内容是否合法,接口返回内容是否符合预期两个方面判断。

查看的关键点:

  • 方法是否正确
  • URL 是否正确
  • 跨域
  • 请求的 Content-Type 是符合要求
  • 请求体格式是否符合要求(JSON/Form)
  • 是否携带了身份信息

合法请求没有得到预期返回,就找后端解决,请求与预期不符就是代码写错了,到错误地方查看代码。

  • 500 等不该出现的异常:500 大概可能是后端问题
  • 404 URL 写错
  • 权限问题:检查请求报文携带的身份信息

4.5 定位到代码应当执行的位置(大概即可)

如果是控制台有错误信息的,利用 sourcemap 可以快速定位到问题出在哪一行。如果没有报错信息,就需要凭借当前页面的状态自己判断出问题的区域,按照代码执行的顺序排查。这一步可以利用的手段比较多,情况也更复杂,需要具体分析。

查看代码运行状态:

  • 按照预期执行顺序检查代码
  • 检查渲染需要的数据是否与预期相同

4.6 按照预期执行顺序检查代码

通过断点、日志等手段判断程序有没有按照自己想要的顺序执行,简单来说就是排查。

4.7 检查渲染需要的数据是否与预期相同

检查运行过程中每一步的数据变化,是否与预期的相同。

4.8 异常代码一般分析方法

  • 「代码注释法」 利用二分法思想逐行去注释代码,直到定位问题
  • 「类库异常,兼容问题」 这种场景也会经常遇到,我们需要用可以调试页面异常的方式,如 SafariWhistlevConsole 查看异常日志,从而迅速定位类库位置,从而找寻替换或是兼容方案。
  • 「try catch」 如果你的项目没有异常监控,那么在可疑的代码片段中去 Try Catch 吧。
  • 「ES6 语法兼容」 一般我们都会通过 Babel 来编译 ES6 ,但是额外的第三方类库如果有不兼容的语法,低版本的移动设备就会异常。所以,先用上文讲述的调试方法,确定异常,然后去增加 polyfill 来兼容吧

五、总结

写到这里整篇文章的调试方法就结束了。也许有很多不到位的地方,专业用词不严谨的地方,希望读者和我一起交流。非常乐意我的调试总结给予前端人受用。

Reference

[1]微信开发者工具: https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html

[2]weinre: http://people.apache.org/~pmuellr/weinre/

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/sxBHC2sRIzTUWsZf7x7a-Q

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237228次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8063次阅读
 目录