[译] 前端调试技巧与诀窍

本文讲的是[译] 前端调试技巧与诀窍,

前端调试技巧与诀窍

编写代码其实只是开发者的一小部分工作。为了让工作更有效率,我们还必须精通 debug。我发现,花一些时间学习新的调试技巧,往往能让我能更快地完成工作,对我的团队做出更大的贡献。关于调试这方面我有一些自己重度依赖的技巧与诀窍,同时我在 workshop 中经常建议大家使用这些技巧,因此我对它们进行了一个汇总(其中有一些来自于社区)。我们将从一些核心概念开始讲解,然后深入探讨一些具体的例子。

主要概念

隔离问题

隔离问题大概是 debug 中最重要的核心概念。我们的代码库是由不同的类库、框架组成的,它们有着许多的贡献者,甚至还有一些不再参与项目的人,因此我们的代码库是杂乱无章的。隔离问题可以帮助我们逐步剥离与问题无关的部分以便我们可以把注意力放在解决方案上。

隔离问题的好处包括但不限于以下几条:

  • 能够弄清楚问题的根本原因是否是我们想的那样,还是存在其它的冲突。
  • 对于时序任务,能判断是否存在时序紊乱。
  • 严格审查我们的代码是否还能够更加精简,这样既能帮助我们写代码也能帮助我们维护代码。
  • 解开纠缠在一起的代码,以观察到底是只有一个问题还是存在更多的问题。

让问题能够被重现是很重要的。如果你不能重现问题来分辨出它到底出在哪里,你将会很难修复这个问题。或者你也可以将它和类似的正常工作的模块进行对比,这样你就可以发现哪里进行过改动,或者发现两者之间有什么不同。

在实际操作中,我有许多种方法对问题进行隔离。其中一种是在本地创建一个精简的测试用例,当然你也可以在 CodePen 创建一个私人测试用例,或者在 JSBin 创建你的用例。另一种是在代码中创建断点,这样可以让我详细地观察代码的执行情况。以下是几种定义断点的方式:

你可以在你代码中写上 debugger;,这样你可以看到当时这一小块代码做了什么。

你还可以在 Chrome 开发者工具中进一步进行调试,单步跟踪事件的发生。你也可以用它选择性地观察指定的事件监听器。

单步调试函数

古老,好用的 console.log 是另一种隔离的方法。(PHP 中是 echo,python 中是 print……)。你可以一小片一小片地执行代码并对你的假设进行测试,或者检查看有什么东西发生了变化。这可能是最耗费时间的测试方式了。但是无论你的水平如何高,你还是得乖乖用它。ES6 的箭头函数也可以加速我们的 debug 游戏,它让我们可以在控制台中更方便地写单行代码。

console.table 函数也是我最喜欢的工具之一。当你有大量的数据(例如很长的数组、巨大的对象等等)需要展示的时候,它特别有用。console.dir 函数也是个不错的选择。它可以把一个对象的属性以可交互的形式展示出来。



上图为 console.dir 输出的可交互的列表

保持条理清晰

当我在 workshop 上做讲师,帮助我的班级的学生时,我发现,思路不够清晰是阻碍他们调试的一大问题。这实际上是一种龟兔赛跑的情形。他们想要行动的更快,因此他们会在写代码时一次就改写很多的代码——然后出了某些问题,他们不知道到底是改的那部分导致了问题的出现。接着,为了 debug,他们又一次改很多代码,最后迷失在寻找哪里能正常运行、哪里不能正常运行中。

其实我们或多或少都在这么做。当我们对一个工具越来越熟练时,我们会在没有对设想的情况进行测试的情况下写越来越多的代码。但是当你刚开始用一个语法或技术时,你需要放慢速度并且非常谨慎。你将能越来越快地处理自己无意间造成的错误。其实,当你弄出了一个问题的时候,一次调试一个问题可能会看起来慢一些,但其实要找出哪里发生了变化以及问题的所在是没法快速解决的。我说以上这些话是想告诉你:欲速则不达。

你还记得小时候父母告诉你的话吗?“如果你迷路了,待在原地别动。“ 至少我的父母这么说了。这么说的原因是如果他们在到处找我,而我也在到处跑着找他们的话,我们将更难碰到一起。代码也是这样的。你每次动的代码越少就越好,你返回一致的结果越多,就越容易找到问题所在。所以当你在调试时,请尽量不要安装任何东西或者添加新的依赖。如果本应该返回一个静态结果的地方每次都出现不同的错误,你就得特别注意了!

选用优秀的工具

人们开发了无数的工具用于解决各种各样的问题。下面,我会依次介绍一些我觉得最有用的工具,并在最后贴上相关资源的链接。

代码高亮

当然,为你的代码高亮主题找一个最热辣的配色与风格方案是很有趣的,但是请花点时间想清楚这件事。我通常使用深色主题,当有语法错误时,深色主题会用较亮的颜色显示我的代码,使我能轻松快速地找到错误。我也尝试过使用 Oceanic Next 配色方案与 Panda 配色方案,但是说实话我还是最喜欢自己的那种。在寻找优秀的代码高亮工具的时候请保持理智,帅气的外观当然很棒,但是为你揪出错误的功能性更加重要。当然,你完全有可能找到两者都很优秀的代码高亮工具。

使用 Lint 工具

使用 Lint 工具能够帮助我们标记出来一些可疑的代码,并且能报出我们忽视的一些错误。Lint 工具相当的重要,使用何种 lint 工具取决于你使用的语言与框架,以及最重要的:你认可怎样的代码风格。

不同的公司有着不同的代码风格及规定。我个人比较喜欢 AirBnB 的 JS 代码规范。你的 Lint 工具将会强制你按照指定的模式进行编程,否则它可以终止你的构建过程。我曾经使用过一个 CSS Lint 工具,当我为浏览器写 css hack 时,它一直在报错。最后我不得不常常关闭它,它也就没能起到应有的作用。但是一个好的 Lint 工具可以把你忽视的一些潜在的问题指出来。

下面是几个资源:

  • 我最近找到了一个响应式图片 lint 工具,它可以告诉你使用 picture 元素、srcset 属性以及 size 属性的时机。
  • 这儿有个很好的分类,收集与对比了一些 JS lint 工具。

浏览器插件

插件是真的超级棒,你可以轻松地启用或禁用它们。并且它们能在特定需求中发挥重要的作用。如果你使用一些特定的框架或类库工作,使用它们的开发者工具插件将会带给你无与伦比的便利。不过请注意,插件不仅会降低浏览器的速度,它们也有权限执行脚本。因此在你使用之前,请先了解一下插件的作者、评价及背景。总之,下面是一些我最喜欢的插件:

  • Deque Systems 提供的 aXe,是一款优秀的可行性分析插件。
  • 如果你工作中使用 React,React DevTools 是你必不可少的工具,你可以通过它观察虚拟 DOM。
  • Vue DevTools,当你使用 Vue 时,同上。
  • Codopen:它会会从编辑器模式弹出 CodePen 的调试窗口。八卦:我老公因为不喜欢看到我一直手动打开调试窗口,所以特意开发了这个工具。(真是个好礼物)
  • Pageruler:它能得到页面中的像素尺寸以及任何需要测量的值。我喜欢这个工具,因为我对于我的布局变态般挑剔。它能帮助我解决这些问题。

开发者工具

这可能是最直观的调试工具了,你可以用它们办到许多事情。它们有着许多内置的特性容易被人所忽视,因此在这个章节中,我们会深入探讨一些我喜欢的特性。

关于学习开发者工具的功能,Umar Hansa 有一套特别好的资料。他制作了一个每周周报与 GIF 动图网站、制作了我们最后一节提到的一个新课程,并在我们网站发表了这篇文章

我最近特别喜欢的一个工具是CSS Tracker 增强插件,收到 Umar 的许可之后我将这个工具在这儿展示给大家看。它会显示出所有没有使用过的 CSS,你可以由此来理解 CSS 对于性能的影响。



上图展示了 CSS tracker 为代码被使用的部分和未被使用的部分按照规则表上不同的颜色。

各色各样的工具

  • What input 是一个能跟踪当前输入(鼠标、键盘、触摸)与当前信息的实用工具。(感谢 Marcy Sutton 提供了这个便捷的工具)
  • 如果你做的是响应式开发,或者你得在无数种设备上进行检查,那么 Ghostlabapp 是个挺适合你的时髦工具。它为你提供了同步移动 web 开发、测试与检查。
  • Eruda 是个很棒的工具,它可以帮助我们在移动设备上进行调试。我很喜欢它,因为它不仅是一个模拟器,还为你准备了控制台和真实的开发者工具,让你更容易理解。

特别提示

我一直对其他人是怎么 debug 的很感兴趣,所以我通过 CSS-Tricks 与我的个人账号在社区征集大家最喜欢的调试方式。以下是社区中大家给出的技巧的合集。

译注:以下如“@xxx -2017年3月15日”格式的文字均为用户在推特上的发言,点击日期可以看到原推特。

辅助方法

$('body').on('focusin',function(){
  console.log(document.activeElement);});

这段代码会记录当前焦点所在的元素。它用起来很方便,因为当你打开开发者工具的时候会将 activeElement 的焦点移除。

-Marcy Sutton

调试 CSS

我们收到很多回复说一些人喜欢在元素外面加上红色的边框(border),以此来观察元素的行为。

@sarah_edo:对于 CSS,我通常会给有问题的元素加上一个 .debug 的 class,这个 class 定义了红色的 border。

— Jeremy Wagner (@malchata) 2017年3月15日

我也会这么做。而且我还做了一个简单的 CSS 文件,可以让我方便地用一些 class 来加上不同的颜色。

检测 React 的 State

@sarah_edo

{JSON.stringify(this.state, null, 2)}

— MICHAEL JACKSON (@mjackson) 2017年3月15日

Michael 提到的这个办法,是我认为最有用的 debug 工具之一。这点代码可以“美观地输出”你当前正在使用的组件的 state,因此你可以了解此时此刻这个组件将会如何变化。你可以确认这个 state 是否和你设想的一样正常工作,它可以帮助你跟踪任何 state 中的错误,以及你使用 state 出现的错误。

动画

我们收到了许多的回复,说他们会在调试时减慢动画速度:

@sarah_edo@Real_CSS_Tricks: * { animation-duration: 10s !important; }

— Thomas Fuchs (@thomasfuchs) 2017年3月15日

我在之前的文章《调试 CSS 关键帧动画》中提到过这个问题,那篇文章里还有更多的技巧,例如如何使用硬件加速、如何在不同时刻进行多种变换等。

我也会使用 JavaScript 将我的动画减速。在 GreenSock 中,以这种形式实现:timeline.timeScale(0.5),它将会将整个时间轴都减速,而不是仅仅将一个动画减速,这个功能超级有用。在 mo.js 中,这个功能是这么写的:{speed: 0.5}

译注:GreenSock 与 mo.js 都是功能强大的js动画库

Val Head 通过屏幕录像做了一个很好的视频,这个视频展示了 Chrome 与 Firefox 开发者工具中提供的动画调试功能。

如果你打算用 Chrome 开发者工具的时间轴来进行性能评估,那么请注意绘制(paint)是最耗性能的步骤,因此当时间轴中绿色占比很高的时候请当心。

检查不同连接状态下的加载情况

我往往在网速很快的条件中工作,所以我会限制我的网速来观察那些网速较慢的人们所体验到的性能。



这是个很有用的功能。它可以与强制刷新、清除缓存结合起来使用。

@sarah_edo:这儿有个不是秘密的小技巧,但是很多人还不知道:打开开发者工具,然后在刷新按钮上右击。pic.twitter.com/FdAfF9Xtxm

— David Corbacho (@dcorbacho) 2017年3月15日

设置定时 Debugger

这一条是 Chris 提供的。对于这点我们写了一篇详细的文章

setTimeout(function() {
  debugger;
}, 3000);

它与我之前提到的 debugger; 工具很类似,不过你可以把它放在 setTimeout 函数中,得到更多详细的信息。

模拟器

@Real_CSS_Tricks 有的 Mac 用户可能还不知道,用 iOS 模拟器加上 Safari 简直不要太方便! pic.twitter.com/Uz4XO3e6uD

— Chris Coyier (@chriscoyier) 2017年3月15日

我前面提到了使用 Eruda 模拟器。iOS 用户还有一种很好的模拟器可以使用。在过去,我会告诉你你得先安装 XCode,但是这条推特提供了一种不同的方法:

@chriscoyier@Real_CSS_Tricks 如果你不想装 XCode,你也可以通过这种方式来使用模拟器:t.co/WtAnZNo718

— Chris Harrison (@cdharrison) 2017年3月15日

Chrome 也有切换设备型号功能,很实用。

远程调试

@chriscoyier@Real_CSS_Tricksjsconsole 是个很棒的工具。

— Gilles (@gfra54) 2017年3月15日

在看到他发的这条推特前,我还真不知道有这么一个好用的工具!

译注,jsconsole 官网现在因为未知原因打不开了,也可以用 Weinre 和 Ghostlab 等工具进行移动远程调试。

调试 CSS 网格布局

Rachel Andrew 也送给我们一个很好的方法。当你使用 Firefox 时,点击一个图标,网格的间隔将会被高亮。她的视频详细地解释了这个技巧。



上图为 Rachel Andrew 展示了如何在 Firefox 开发者工具中将网格的间距高亮。

数组调试

Wes Bos 提供了一个在数据中搜索元素的一个很有用的技巧:

你可以用 array.find 来查找元素 t.co/AuRtyFwnq7

— Wes Bos (@wesbos) 2017年3月15日

更多调试相关的资源

Jon Kuperman 制作了一个 “前端能手课程”,这个课程将会通过这个 app 来帮助你掌握开发者工具的使用。

code school 的一个小课程:发现开发者工具

Umar Hansa 的一个新的在线课程: 现代开发者工具

Julia Evans 写了一篇很不错的 关于调试的文章,在此向 Jamison Dance 致谢,感谢他让我看到这么好的文章。

Paul Irish 总结了一些 使用开发者工具进行性能检查的高级技巧。如果你和我一样是个书呆子,可以把它收藏起来深入研究。

在文章的最后,我将放上一个让人喜忧参半的资源。我的朋友 James Golick 是一位杰出的程序员,在多年以前做过一个关于 degub 的会议讲话。虽然 James 去世了,但是我们仍然能在这个视频中回忆他、向他学习。






原文发布时间为:2017年4月27日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2024-11-03 18:04:44

[译] 前端调试技巧与诀窍的相关文章

一探前端开发中的JS调试技巧

友情提示:文中涉及较多Gif演示动画,移动端请尽量在Wifi环境中阅读 前言:调试技巧,在任何一项技术研发中都可谓是必不可少的技能.掌握各种调试技巧,必定能在工作中起到事半功倍的效果.譬如,快速定位问题.降低故障概率.帮助分析逻辑错误等等.而在互联网前端开发越来越重要的今天,如何在前端开发中降低开发成本,提升工作效率,掌握前端开发调试技巧尤为重要. 本文将一一讲解各种前端JS调试技巧,也许你已经熟练掌握,那让我们一起来温习,也许有你没见过的方法,不妨一起来学习,也许你尚不知如何调试,赶紧趁此机会

14个你可能不知道的JavaScript调试技巧

以更快的速度和更高的效率来调试JavaScript.熟悉工具可以让工具在工作中发挥出更大的作用.尽管江湖传言 JavaScript 很难调试,但如果你掌握了几个技巧,就能用很少的时间来解决错误和bug.文中已经列出了14个你可能不知道的调试技巧,但是可能需要你牢记在心,以便在下次需要调试JavaScript代码时使用!  1. debugger  除了console.log, debugger是我们最喜欢.快速且肮脏的调试工具.执行代码后,Chrome会在执行时自动停止.你甚至可以把它封装成条件

VS2010中的调试技巧

这是我的博客中关于VS 2010和.NET 4发布系列的第二十六篇文章. 今天的博文将介绍Visual Studio中的一些实用调试技巧.这是受我朋友Scott Cate (他发表过几十篇很棒的VS技术文章) 启发.他最近告诉我,许多Visual Studio下的程序员,甚至一些很有经验的开发人员,都不知道这些技巧.希望这篇文章能帮你掌握这些技巧.它们都很简单,却能帮你节约大量的时间. 跳到当前光标处(Ctrl+F10) 我经常看到人们为了到达目标代码位置,而在程序中早早设定了断点,然后反复地按

轻松使用DOM 的技巧和诀窍

Dethe Elza (delza@livingcode.org), 高级技术架构师, Blast Radius  文档对象模型(Document Object Model,DOM)是用于操纵 XML 和 HTML 数据的最常用工具之一,然而它的潜力却很少被充分挖掘出来.通过利用 DOM 的优势,并使它更加易用,您将获得一款应用于 XML 应用程序(包括动态 Web 应用程序)的强大工具. 本期文章介绍了一位客串的专栏作家,同时也是我的朋友和同事 Dethe Elza.Dethe 在利用 XML

Google Adsense的技巧、诀窍和秘密

我最近一直在阅读一些关于Google Adsense技巧的论坛和博客,我觉得有必要将这些技巧都集中整理在一个地方,同时我也写了几个我自己的诀窍.我们开头先讲一些最基本的一般性常识,然后再逐步深入讨论一些更为具体的主题. 建立一个帝国? 当你决定成为一个网站广告发布者时,你会陷入两个不同类型的怪圈: 发布100个每天赚1美元的网站. 发布1个每天赚100美元的网站. 目前的现实是,大部分人最终会成为这两者之一.拥有100个网站会让你疲于维护.管理以及内容建设.拥有1个网站会让你承受各种各样的波动和

javascript 调试: javascript调试技巧之:快速定位

赶紧总结一下javascript的调试技巧,这次首先是"快速定位"篇.快速定位,其实就是快速定位程序的错误,所以也算是调试.这个在实际的码代码时往往比较实用.大多数情况下,你的js代码不多(少于1000行),只要能迅速发现代码的错误,往往不用复杂的调试.关于常用的快速定位方法,我总结了一下几点,欢迎大家补充.1. 使用alertalert其实比较实用.本地调试中,在合适的位置写alert,打出来一些变量,虽然比较土,但是往往事半功倍!另外有一个alert技巧,想看看一个对象中的属性和它

C++编程语言的四个调试技巧

1.调试标记 适用预处理#define定义一个或多个调试标记,在代码中把调试部分使用#ifdef和#endif进行管理.当程序最终调试完成后,只需要使用#undef标记,调试代码就会消失.常用的调试标记为DEBUG, 语句序列: #define DEBUG#ifdef DEBUG调试代码#endif 2.运行期间调试标记 在程序运行期间打开和关闭调试标记.通过设置一个调试bool标记可以实现.这对命令行运行的程序更为方便.例如下面代码: #include<iostream>#include &

.NET程序调试技巧(一):快速定位异常的一些方法

  这篇文章主要介绍了.NET程序调试技巧(一):快速定位异常的一些方法,本文讲解了定位本机异常.在客户环境定位.net程序异常两方面的内容,需要的朋友可以参考下 作为一个程序员,解BUG是我们工作中常做的工作,甚至可以说解决问题能力是一个人工作能力的重要体现.因为这体现了一个程序员的技术水平.技术深度.经验等等. 那么在我们解决BUG的过程中,定位问题是非常重要的.有句话叫"发现问题是解决问题的一半. 本文讲述就快速定位异常(专指.NET程序异常)的方法.包括在本机定位异常,在客户环境定位.n

调试技巧之调用堆栈

简单介绍 调试是程序开发者必备技巧.如果不会调试,自己写的程序一旦出问题,往往无从下手.本人总结10年使用VC经验,对调试技巧做一个粗浅的介绍.希望对大家有所帮助. 今天简单的介绍介绍调用堆栈.调用堆栈在我的专栏的文章VC调试入门提了一下,但是没有详细介绍. 首先介绍一下什么叫调用堆栈:假设我们有几个函数,分别是function1,function2,function3,funtion4,且function1调用function2,function2调用function3,function3调用