调试能力是衡量一个开发者水平的重要指标。在编写应用时,首先应该了解如何调试应用程序。通过调试,我们可以清晰地看到程序在运行过程中的具体执行状态。
本节将通过调试请求过程和异常信息来演示如何在VS Code中调试Nest。
图2-46 创建nest-debug项目
首先,运行nest n nest-debug命令创建一个项目,如图2-46所示。
在项目中运行nest start--watch–debug命令,可以启动应用并开启热重载以及调试模式,运行成功后,效果如图2-47所示。
图2-47 控制台上的运行结果
访问http://localhost:3000/,可以看到正常返回的内容,如图2-48所示。
图2-48 浏览器上的运行结果
除此之外,Nest启动了一个如图2-47所示的端口为9229的WebSocket服务。我们只需要连接这个端口就可以进行调试了。在Chrome中输入chrome://inspect后按Enter键,显示已经连接上远程调试目标,连接的正是nest-debug这个项目,如图2-49所示。
图2-49 连接调试目标
其中,Configure是用来配置端口号的。我们可以设置调试服务的端口,Nest中默认是9229,如图2-50所示。
图2-50 默认9229端口
当然,可以在启动服务时修改端口号,比如输入nest start --watch --debug 8083,此时启动的就是8083端口,如图2-51所示。然后在Configure中配置即可连接。
图2-51 自定义调试端口
在图2-49中单击inspect,导入项目文件夹,在app.Controller.ts的getHello()方法中添加一个断点。刷新页面之后,可以看到代码自动在断点处停下,如图2-52所示。
图2-52 断点演示效果
这样就完成了使用Chrome浏览器调试Nest应用的过程。然而,这种方法可能不太方便。我们通常会使用VS Code等集成开发环境(IDE)进行开发。那么,能否直接通过这些工具进行调试呢?答案是肯定的。接下来将详细讲解。
在终端窗口通过命令“nest start --watch –debug”启动调试服务,如图2-53所示。
图2-53 启动调试服务
接着在需要调试的地方打个断点,如图2-54所示。
图2-54 在指定行打断点
然后在http://localhost:3000/地址刷新浏览器,此时程序会直接在断点处停下,如图2-55所示。
图2-55 断点效果
这种方式是否比之前的方法更简单呢?确实如此。无论是Chrome DevTools还是VS Code等第三方集成开发环境(IDE),它们都通过CDP(Chrome DevTools Protocol)协议实现了调试服务的功能。
有些读者可能会提出这样的问题:我不想每次都手动输入--debug参数,能否在执行“yarn start:dev”命令后自动进入调试模式?
当然可以。你只需在package.json文件中添加一个脚本(script)命令即可实现这一点。在Nest项目中,这个脚本默认就已经存在了,如图2-56所示。
图2-56 package.json中的scripts配置
确实,使用Nest CLI的--debug参数可以方便地启动调试模式。但如果是其他Node.js脚本,情况就不同了。这正是笔者想要提到的:VS Code提供了一个便捷的自动附加模式。
要使用这个功能,你可以通过按快捷键Command+Shift+P(在Windows中)或Ctrl+Shift+P(在Linux中),然后在弹出的命令面板中输入“Toggle Auto Attach”,接着选择“总是”选项,以自动附加调试器到Node.js进程,如图2-57所示。
图2-57 VS Code自动附加
重新打开控制台并运行“yarn start:dev”命令,此时VS Code在启动应用的同时,也会自动创建一个调试器(debugger)服务。该调试服务的默认端口号为61174,如图2-58所示。
图2-58 附加模式启动效果
重新在浏览器中访问http://localhost:3000/,依然可以进入断点调试状态,如图2-59所示。
图2-59 调试效果
以上两种方式会在每次执行命令时创建一个新的WebSocket调试服务。然而,对于一些开发者来说,这种方法可能并不适合他们的需求。接下来,在2.6.3节中,我们将探讨一些扩展的调试技巧。
前面讲解了基于--debug参数来启动调试服务,如图2-60所示。从CLI源码中可以看到,本质上还是执行“node xxxx –inspect”命令来运行的。
图2-60 --debug参数的定义
因此,我们也可以选择在VS Code中使用这种方式进行调试。首先,在调试面板中单击创建launch.json文件的选项,如图2-61所示。
图2-61 创建launch.json调试文件
然后选择Node.js作为调试器,如图2-62所示。
图2-62 选择Node.js调试器
接着根据需要配置相关的调试信息。在launch.json文件中,将program字段的值修改为你的应用程序的入口点,例如main.ts:
配置完成之后,在app.service.ts的getHello()方法中添加断点,单击左上角的“启动调试”按钮,如图2-63所示。
图2-63 打断点并启动调试
可以看到在“调用堆栈”中新增了一个启动程序,这就是VS Code调试器。我们依旧在Chrome中访问http://localhost:3000/,此时程序自动在断点处停住,并且在左侧可以看到调用栈信息和变量情况,如图2-64所示。
图2-64 调试调用栈情况
这种方法的优势在于它避免了每次启动都需要创建一个新的WebSocket调试服务,从而节省了运行时的内存消耗。调试程序仅在需要时启动,这正是我们最常用的调试方式。它适用于前端应用,如Vue、React以及Node.js等多种应用的调试。