相关章节ChromeDevtools:ElementsOverviewSources面板用于资源检索和代码逻辑调试。预演示示例ElementUI官网其他章节以掘金为例进行演示,而掘金是服务端渲染(SSR)、资源压缩、演示难度大。环境Chrome浏览器版本90.0.4430.93操作定义关注控制台在控制台范围内点击鼠标,将后续操作上下文绑定到控制台。打开控制台以ElementUI官网为例:通过链接打开页面,通过F12或鼠标右键【勾选】打开开发者工具控制台。资源管理器面板的默认布局被细分为不同的面板。默认显示是页面面板。页面面板默认按域名分类,列出站点依赖的所有资源。代码编辑面板在资源管理器面板中选择一个文件,在面板中显示文件内容和调试面板。它只是细分为下面板来管理不同的资源:Page面板管理远程站点资源Filesystem面板使用Sources面板作为IDE(代码编辑器),管理本地站点资源Snippets面板管理浏览器持久代码资源我们使用Page面板作为主体Narration,和其他小面板(文件系统、片段)经过。Pagepanel面板布局1:资源管理器的默认布局是Pagepanel的全部内容。该面板列出了当前站点页面执行的所有资源。我们可以通过该面板获取以下站点信息:技术栈:可以从资源中获取关键代码查看相关资源:从资源列表中可以一目了然地看到页面加载的资源类型。当前页面执行的自定义脚本,比如在Snippets面板中定义的...依赖域:从资源分类来看,依赖资源所在的域一目了然Browserextensions加载到的浏览器扩展当前页面消除了一个干净的调试环境的扩展干扰。因此,隐身模式一般用于调试。先决条件:未启用任何扩展。面板布局二:代码编辑面板在页面面板中点击任意一个资源,可以在默认布局的编辑面板中看到资源详情2.点击上图中的图片资源,可以看到图片是二维码.点击上图中的CSS资源,在默认布局的位置2的编辑面板中,可以点击左下角的{}按钮进行代码美化——美化时间根据大小不同而不同当前的CSS资源。如果资源太大,浏览器可能会因CPU使用率过高而卡顿。这里我们做了一个实验,取回顶部菜单的selector,更新样式,可以实时看到页面上的显示效果,甚至不用保存。不过这里修改的代码只是保存在内存中,页面刷新时代码会恢复。JS资源调试这里我们单独介绍Javascript资源,因为在Devtools中调试JS资源的复杂度比较高。调试JS的场景在写代码的过程中,检查未知参数的结构;在编写和bug修复过程中,当运行结果与逻辑设计不符时,梳理代码逻辑;在熟悉代码的前提下,从规律出发,推断出bug重现的范围,以及在不同范围内命中(条件)断点。逐步调试断点。对于发现的问题,提出解决方案,对方案进行评估,选择合适的方案进行修复。注意:对于网络请求,断点时间过长会造成请求超时。断点vs.日志在调试代码时,常用的方法有两种:断点和日志;breakpointsDebuggerlogsConsole中断代码执行不中断代码执行检查代码被中断时刻的上下文信息检查代码执行结束上下文信息是非侵入式和侵入式的。将日志代码写入业务代码,查看代码中断时的所有执行上下文信息。只能查看指定的打印信息及时性:此时的值代码执行结束时指定信息的值,除非Deepcopyexample在代码编辑面板中,只有Javascript的断点才能拦截成功执行,并且对于DOM的断点,需要在Elements面板添加:DOM操作,详见Elements。下面以Chrome浏览器官方提供的调试代码为例:打开控制台,从Panel面板可以看到当前页面只有两个资源:HTML页面和相关的JavaScript。其他是我安装的Chrome扩展程序(未使用隐身模式)。从get-started.html中,我们可以看到相关的HTML结构、Style风格和导入的JavaScript代码。页面逻辑输入Number1,Number2,点击按钮得到计算结果。计算预期结果,得到Number1和Number2之和:1+1=2实际结果是Number1和Number2的字符串拼接:1+1=11复现率为100%,说明是一个逻辑错误,而不是代码逻辑没有覆盖某种边界的概率问题。代码锁定错误范围(可疑)functionupdateLabel(){varaddend1=getNumber1();varaddend2=getNumber2();varsum=加数1+加数2;label.textContent=addend1+'+'+addend2+'='+sum;}从代码中猜测label.textContent=addend1+'+'+addend2+'='+sum;而1+1=11的显示结果,addend1和addend2好像没有问题,但是sum好像有问题,那我们就把sum计算的点打断。断点调试在资源管理器中点击html导入的Javascript文件,找到相关代码,点击行号添加断点,再次点击相同行号取消断点。点击按钮触发函数调用。这时候我们可以看到当前执行上下文中的所有信息,比如addend1和addend2的值。如果我们偷偷执行F9(Step),就可以看到sum的结果。诊断从当前的执行上下文可以看出,addend1和addend2的值都是字符串类型,字符串相加就是字符串的拼接,所以结果是没有问题的!!!是的,计算结果很好,为什么不是我们预期的结果呢?因为我们希望数字类型相加!!!测试重点在控制台,Console面板可以通过按下ESC键在当前面板中打开/隐藏,位于控制台底部。使用断点将作用域限制在updateLabel函数中,通过Console面板验证你的猜想。此时Console面板可以访问函数updateLabel的变量。解决方案那么我们只需要将addend1和addend2的值转换成数字即可。解决方法有很多种:parseInt()parseFloat()Number()1*'1'...这里我直接在代码编辑器面板中改了getNumber1和getNumber2的方法,返回的是numeric类型的数据。保存后,点击按钮可以看到想要的结果。通过右上角的按钮,切换断点的激活状态,激活为深蓝色,停用为蓝色透明。停用时,断点不会拦截代码执行。在停用状态下,可以尝试输入不同的值来检查逻辑的正确性。简单的调试示例到此结束。CSS、JavaScript调试vs.JavaScript调试CSS调试需要保存不需要保存需要手动执行调用,不会自动执行,可以截取实时效果执行。用于在自己编写的程序中进行调试。如果遇到其他场景,比如第三方库调试,需要根据对应场景选择合适的断点组合。断点类型应用场景代码行断点一般/清楚知道调试范围使用代码行条件断点一般/清楚知道调试范围,只使用代码行日志断点在指定条件分支下调试非代码侵入式打印LogDOM断点调试指定DOM变化、移除或子节点变化,详见ElementsXHR断点调试URL包含指定字符串请求事件监听断点调试指定元素事件触发逻辑使用比较时使用事件委托建议使用黑框+无痕的错误断点调试错误捕获的模式。一般只用于调试未捕获的错误代码行。当可以通过问题重现推断出清晰的调试代码范围时,可以使用断点。在代码编辑面板中右键点击行号或者直接点击行号添加代码行断点。代码行条件断点在有中介时使用,协调处理逻辑或条件分支的分配,排除其他逻辑的干扰,聚焦重点。从上图可以看出,在代码编辑面板中右击行号,选择AddConditionalBreakpoint...,就可以在代码行中添加条件断点。添加条件断点时,如果条件为真,代码执行将被拦截,如果条件为假,则不会被拦截。当至少有一个输入框为空时,断点有效,当所有输入框都不为空时,断点无效。代码行日志断点不需要侵入源码,如上图实现非侵入式日志打印。输入格式为console.log函数的参数形式。如上所示,您可以显式使用控制台对象的其他方法来打印日志DOM断点。有关详细信息,请参阅元素一章中的XHR断点。找到一个请求,将其添加到XHR断点,然后重新加载页面。请求发送时,代码逻辑会被拦截,可以查看相关的请求参数。事件监听断点EventListenerBreakpoints如果你对代码不熟悉,或者在长代码逻辑中,只知道点击触发业务处理逻辑,可以考虑事件监听断点。然而,在复杂的事件委托中,是一场噩梦。注意:在隐身模式下使用时,浏览器扩展可能会干扰。错误断点启用错误断点,默认会拦截未处理的错误逻辑。如果选择了Pauseoncaughtexceptions,捕获到的错误逻辑也会被拦截。Blackbox(Ignorelist)Blackbox(旧版叫blackbox,新版浏览器更名为ignorelist)是个小功能,单独拉出来,因为不适合和其他分类合并.使用此功能可以集中注意力并排除非核心或受信任代码的干扰。由于该示例是一个非常简单的示例,因此在此借助事件监听器断点来描述该功能的使用。在Click事件上加断点,点击AddNumber1和Number2按钮,onClick函数的第一行就会被截取,OK!重新加载页面,在代码编辑面板中打开可信代码,右键添加Addscripttoignorelist,再次点击AddNumber1和Number2按钮,你会发现代码逻辑完全没有被拦截执行。对比以上场景,我们可以发现黑盒帮助我们关注相关逻辑代码,跳过一些可信(认为不会有bug)的库,比如:jQuery?一步一步调试的时候,我们不会进入jQuery库调试,专注于自己的逻辑。代码覆盖率可以帮助我们找到无效(Never)代码。通过代码编辑面板右下角的Coverage,我们可以查看代码的覆盖率。如上图所示,页面初始化执行时,代码未覆盖率为41.9%,即页面初始化时有41.9%的代码没有执行。点击AddNumber1andNumber2按钮,执行输入验证相关的代码逻辑。代码未覆盖率为17.3%,即仍有17.3%的代码没有被执行。输入input,点击AddNumber1andNumber2按钮,执行计算相关的代码逻辑。代码未覆盖率为0%,即代码逻辑全部执行。在某种程度上,它可以帮助我们找到Neverinvalidcodes。面板布局三:调试面板单步执行在调试代码的过程中,我们需要控制代码的执行:如上图所示,添加三个断点,添加一条日志。触发一个事件,点击Resumescriptexecution,代码会继续执行,直到遇到下一个断点。如果在拦截过程中按住Resumescriptexecution,并选择下拉按钮的第一项,则后面的断点将被跳过,代码将被完整执行。可以看到日志已经执行了一次。如果拦截时按住Resumescriptexecution,选择下拉按钮的第二项,则后续代码执行会强制停止在拦截点,可以看到后续逻辑中的日志没有执行。重新加载页面以将页面恢复到其原始状态。调试面板最上面一行的工具控制断点被拦截时代码的执行,Resume按钮恢复代码的执行,直到遇到下一个断点。如果断点所在代码行的表达式是一个函数,stepover按钮会跳过函数内部的执行,如图15行(15L),下一步直接执行到16L.如果断点所在代码行的表达式是一个函数,则stepinto按钮会深入到函数内部执行,如图中第15行(15L)所示,下一步进入函数的内部并执行到22L。执行到22L后,如果不想再调试函数inputsAreEmpty,可以通过stepout跳出函数的执行,如下图,下一步直接跳出函数的执行当前函数并执行到16L。思考:如果点击22L处的Stepinto按钮,那么下一步会在哪里执行呢?如果点击22L处的Stepthrough按钮,下一步会在哪里执行?最后,看看步骤按钮。步扣是一个实名的老实人。遇到高山就爬山,遇到大海就潜水,逻辑上的每一步都会去。当你遇到一个函数时,你会深入到函数代码中去执行每一步。如果逻辑中没有函数,则stepover、stepinto、stepout、step的行为与step一致。停用(Deactivate)、停用(disable)断点看下图,分别执行停用和停用,明白了吗?在上图中,添加了两种类型的断点。第一次正常执行时,三个断点都会被执行。第二次禁用断点,点击AddNumber1和Number2,执行代码,断点没有被拦截。第三次激活断点(restoredisabled),关闭断点,点击添加Number1和Number2,代码在Click事件处理逻辑的第一行被拦截,后续断点不被拦截。模糊?总结:停用是有范围的,只有代码行断点停用,其他类型的断点不停用。Disabled表示所有类型的断点都不会被触发。监听重新加载页面,删除所有断点。可以在Watch中添加表达式来监听每个执行时间点的值。函数调用的监听会影响代码逻辑的执行。比如上图中的inputsAreEmpty()就是作为Watch表达式使用的。当Watch需要更新显示时(计时:代码执行到表达式所在域),Chrome会自动调用该函数获取函数的最新返回值。如果在inputsAreEmpty()的函数逻辑中加断点,会无限循环。在inputsAreEmpty()的代码行加个断点,函数体会执行3次。第一次,到达作用域时的初始值。因为inputsAreEmpty()函数体中没有断点,更新Watch表达式后,就没有其他机会更新表达式了。在inputsAreEmpty()函数体中添加代码行断点,函数体将无限执行。inputsAreEmpty()第一次执行域初始化时第二次执行inputsAreEmpty()。第三次执行inputsAreEmpty()后,更新Watch。第四次更新手表。执行inputsAreEmpty()。第五次执行inputsAreEmpty()后,第六次更新Watch...所以,不建议在Watch表达式中添加函数调用。Scope在拦截代码执行时,我们可以在调试面板的Scope部分看到当前作用域Local的变量,比如上图中的这个。继续执行代码到return语句,可以在当前作用域Local看到返回值ReturnValue。双击范围中的值以更改当前值。Global作用域可以看到全局作用域的变量和方法。默认情况下,Console面板只能访问全局变量和函数,但是当断点被拦截时,Console面板可以访问当前范围内的方法和变量。CallStackCallStackCallStack,可以看到当前正在执行的函数的源码,帮助我们追根溯源。在当前执行函数上右击,点击重启框架,重新执行当前函数的逻辑。在大代码段的调试中使用更方便。仅限于断点执行的函数,已经通过的函数无效。Filesytem面板浏览器就是如上所示的代码编辑器,在本地启动服务打开一个静态页面,在Sources面板下的Filesystem面板中将静态项添加到工作区。通过Elements面板定位到一个DOM节点的锚点,直接在Styles面板中调试样式。重新加载页面后,样式仍然有效。通过查看样式的源代码可以发现,在样式面板中调试的样式已经存盘覆盖了原来的样式。适用场景静态页面的CSS和JavaScript在上图中,我们可以看到Filesystem中的一些文件的文件名中有小绿点。绿点表示浏览器打开的文件与本地磁盘建立了连接。浏览器调试时可以直接映射修改后的文件。静态页面的HTML通过Elements面板eidt到本地磁盘。HTML无法保存到磁盘。元素面板映射到DOM树。DOMTree的生成受HTML、CSS(内容样式属性)和JavaScript动态处理的影响。因此,浏览器无法将DOMTree的变化映射到相应的位置[推荐]在结构、表现、动态效果(HTML、CSS、JavaScript)分离的静态页面项目中快速调试使用。InvalidScenarios构建工具打包的项目即使使用了sourceMap,复杂的文件映射关系也会导致浏览器与本地磁盘的连接脆弱不可靠。上图附加了一个检测浏览器类型的Javascript脚本。Ctrl+S保存后,可以打开其他选项卡,仍然可以在Snippets面板中看到脚本。点击右下角的执行按钮或者通过快捷键Ctrl+Enter执行这个脚本,在下方的控制面板中可以看到执行打印出来的日志。SnippetsConsole跨标签可用当前标签可用于永久存储,除非在页面重新加载后手动删除和清除
