如何通过VsCode优雅调试Nest
调试能力是衡量一个开发者水平的重要指标,在编写应用的时候,首先应该要知道如何调试应用,通过调试,我们可以清晰看到程序在运行过程中的裸奔状态。
接下来,通过调试请求过程和异常信息来演示VsCode
如何调试Nest
创建launch.json
点击调试,创建launch.json
调试文件
选择Node.js
调试器
修改program
地址为入口文件
json
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/src/main.ts",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
切换开关自动附加(Toggle Auto Attach)
服务启动时自动开启debug服务
Mac
中通过command + shift + control
打开命令行窗口,输入Toggle Auto Attach
选择总是
这时候状态栏红会出现自动附加:始终
这时候运行Nest
服务的时候,自动拉起debugger
服务,那么两个服务共享一个端口
此时可以看到debug栏中已经启动了调试服务
这时候,我们通过前端发送一个请求来测试一下调试效果,在匹配到POST
请求路由的时候进行断点
点击按钮获取nest
返回的数据
此时,会自动定位到断点位置,并且能够成功拿到前端post
的数据。
接下来再看一下异常情况,修改一下前端传递name
参数的类型为number
类型
正常情况会抛出异常(DTO验证
),被全局异常拦截器捕获,并且可以看到具体的错误信息!
手动开启debug服务
很多时候不希望跑
dev
服务的时候直接开启调试,毕竟在一些机器上占用多一个进程会导致VsCode变卡,所以在需要的时候手动开启调试。
将自动附加设置为禁用
手动启动调试服务,依然可以进入正常的debug
需要注意的是,这时候不用手动启动nest dev
服务,否则会导致两个服务的端口冲突。细心的朋友可以留意到两种方式启动的时候,左边调用堆栈
运行的程序跟前面的是有区别的
调试源码
了解了这两种调试方式之后,也可以直接来调试源码,比如调试一下nest
中Post
装饰器是如何实现的?
在Post
装饰器打个断点,重新启动调试
这里的程序会在node
初始化模块的时候断住
说到这里,稍微扩展一下,通过这种调试方式,是可以看到node
在加载和执行模块的流程原理,怎么看呢?
点开这个调用栈信息
可以看到node
首先是通过Module.load
加载模块,而这里加载的是js
模块,然后根据sourceMap
定位到具体TS源码的位置,所以断点可以直接在TS源码中进行断住。
Module._extensions
判断文件类型进行读取操作,node
中读取文件都是字符串的,所以很多工具底层其实是直接对字符串进行操作,例如通过拦截这个方法实现批量脱敏的操作。
Module._compile
对文件进行编译、设置断点等操作
--inspect-brk
这个也是一种调试方式,它会在代码启动的首行进行断住,这里就不牵扯太多了,扩展这个只是为了说了通过调试可以一步一步看程序是如何运行的,这是学习其他框架源码非常有效的方式。
再回来看一下@Post
是如何实现的?进入函数内部看看
这里是一个装饰器工厂,接收不同的请求类型和路由参数,看到这里基本上就能够结合ES6 decorate
自己实现一个类似的装饰器。
再进入一层就涉及到元数据-metedata
相关的知识点了,在Vue2
中使用reflect-metadata
包实现类似Vue3 compositionAPI
的编码风格就是利用这玩意儿,这里不再展开说啦~
总结
通过上面两种调试方式可以轻松的对Nest
应用进行调试,根据自身的实际情况进行选择。当然,我们在调试源码的过程中也还发现了另外一种--inspect-brk
命令行断点方式,类似的还有--inspect
方式,掌握了以上技巧,code中遇到问题就不用侵入式每个地方进行console
。