likes
comments
collection
share

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

作者站长头像
站长
· 阅读数 52

调试:指的是代码在某个平台运行,把运行时的状态通过某种方式暴露出来,传递给开发工具做 UI 的展示和交互,辅助开发者排查问题、梳理流程、了解代码运行状态等。

frontend(前端)、backend(后端)、调试协议、信道,这是调试工具的四要素。

三种调试工具原理

Chrome DevTools 调试

用 Chrome DevTools 调试网页,可以查看元素,网络请求,断点运行 JS,用 Performance 工具分析性能等

Chrome DevTools 分为两部分,backend(后端) 和 frontend(前端):

  • backend 和 Chrome 集成,负责把 Chrome 的网页运行时状态通过调试协议暴露出来。
  • frontend 是独立的,负责对接调试协议,做 UI 的展示和交互。

两者之间的调试协议叫做 Chrome DevTools Protocol,简称 CDP。

传输协议数据的方式叫做信道(message channel)

Chrome DevTools 由(frontend、backend、调试协议(CDP)、信道) 4 个组成部分

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

图中的,backend 可以是 Chromium,也可以是 Node.js 或者 V8,这些 JS 的运行时都支持 Chrome DevTools Protocol。

VSCode Debugger 原理

VSCode Debugger 的原理和 Chrome DevTools 差不多,也是分为 frontend、backend、调试协议这几部分,只不过它多了一层适配器协议。

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

中间多了一层适配器协议 Debug Adapter Protocol,这是为什么呢?

因为 VSCode 不是 JS 专用编辑器呀,它可能用来调试 Python 代码、Node 代码等等,自然不能和某一种语言的调试协议深度耦合,所以多了一个适配器层。

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

VSCode Debugger 的 UI 的部分算是 frontend,而调试的目标语言算是 backend 部分,中间也是通过 WebSocket 传递调试协议。

Vue/React DevTools

Vue DevTools 或者 React DevTools 都是以 Chrome 插件(Chrome Extension)的形式存在的

Vue DevTools 也是分为 backend 和 frontend 的

Chrome 插件中可以访问网页的 DOM 的部分叫做 Content Script,随页面启动而生效,可以写一些操作 DOM 的逻辑。还有一部分是后台运行的,叫做 Background,浏览器启动就生效了,生命周期比较长,可以做一些常驻的逻辑。

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

如果是扩展 DevTools 的 Chrome 插件,那还有一部分 DevTools Page,是在 DevTools 里显示的页面

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

DevTools Page 部分渲染出的界面是这样的:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

VsCode断点调试方法

异常断点

代码抛了异常,你想知道在哪抛的,这时候就可以用异常断点。

比如下面一段代码:

function add(a, b) {
    throw Error('add');
    return a + b;    
}

console.log(add(1, 2));

add 函数里抛了个异常,你想在异常处断住,这时候就可以加个异常断点:

勾选异常断点选项

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

可以在没有被处理的错误或者 Promise 的 reject 处断住。

上面那个 Caught Exception 是在被 catch 处理的异常出断住。

对应中文调试界面

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

运行过程和结果:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

条件断点

有的时候我们只想在满足一定条件的时候才断住,这时候就可以用条件断点

在代码左边打断点的地方右键单击,就可以选择条件断点:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

添加一个表达式,比如我只想在 a 等于 3 的时候断住:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

下面打印了两次,但是只断住符合条件的一次 前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

LogPoint

LogPoint 是在控制台打印日志,和console·log()差不多,但是console·log()打印实际上是浏览器保存了我们输出对象的信息数据引用,会造成代码污染和内存泄漏。

logpoint不会造成代码污染和内存泄漏,它就是个断点的设置,不在代码里。

添加一个 LogPoint:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

输入打印的表达式:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

跑一下 node 调试,你会发现打印了日志,但没有断住:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

核心调试方法 (Debugger 调试)

debugger 调试,调试复杂源码

为什么弃用console.log

很多同学用的是 console.log 调试,把想看的变量值打印在控制台。

console.log打印弊端: console.log打印时,当打印的对象值,也是对象时,就无法展开打印的对象了,而是打印一个 [Object] [Array] 这种字符串,根本没法看;更致命的是打印的太长会超过缓冲区的大小,terminal 里会显示不全。

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

有的同学会问,打印一个具体的属性值可以用console.log了吧,如果要打印一个对象值的话,为啥不考虑用LogPoint,他和console.log的优劣上面说过了,明显是LOgPoint更加完美。

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

代码执行到这里就会打印:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

而且用 console.log 的话调试完之后,作为合格的程序员 console.log 也是删掉的。

Debugger 调试

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运 最重要的是 Debugger 调试是可以看到调用栈和作用域的!

调用栈:指代码的执行路线

比如这个 App 的函数组件,你可以看到渲染这个函数组件会经历 workLoop、beginWork、renderWithHooks 这些流程:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

你可以点开调用栈的每一帧看下都执行了啥逻辑,用到啥数据。比如可以看到这个函数组件的 fiber 节点:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

再就是作用域,点击每一个栈帧就可以看到每个函数的作用域中的变量:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

经典操作

在排查问题的时候,用 Debugger 的话可以加一个异常断点,代码跑到抛异常的地方就会断住 前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

可以看到调用栈来理清出错前都走了哪些代码,可以通过作用域来看到每一个变量的值。

有了这些东西,排查错误不就很轻松了么!

Performance性能(辅助调试)

Debugger 调试可以看到一条代码的执行路径,但是代码的执行路径往往比较曲折。在浏览器工具中,有一个Performance 工具,可以看到代码执行的全貌。

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

SourceMap(调试源码)

我们执行的都是编译打包后的代码,基本是不可读的,调试这种代码也没啥意义,而 sourcemap 可以让我们直接调试最初的源码。

比如 vue,关联了 sourcemap 之后,我们能直接调试 ts 源码:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

nest.js 也是:

前端三种调试工具,3种常用VsCode断点调试方法,核心调试方法 (debugger 调试)调试:指的是代码在某个平台运

总结

我们调试、打断点,根本原因就是对代码逻辑、语法等等不够熟悉,做调试就是为了熟悉每一行代码。

读懂了一行,然后读懂一个函数,最后读懂一个小功能的实现流程

转载自:https://juejin.cn/post/7246778044022259767
评论
请登录