介绍日志点和自动附加
2018年7月12日 Kenneth Auchenberg, @auchenberg
在过去的几个月里,我们一直在忙于改进Visual Studio Code中的调试体验,在这篇文章中,我将讨论我们如何看待调试,展示我们从用户那里听到的反馈,并解释我们正在采取哪些步骤来使VS Code中的调试变得更加容易和简单。
自从VS Code推出以来,我们就集成了调试体验,因为我们相信调试应该是你编写和编辑源代码的地方——你的编辑器——的一个不可或缺的部分。
VS Code 的调试体验由一个通用的调试器用户界面提供支持,该界面通过调试适配器协议(DAP)与一种特定类型的 VS Code 扩展(我们称之为调试适配器(DA))进行通信。调试适配器与实际的调试器进行对话,并在 DAP 和调试器的运行时特定调试协议或 API 之间进行转换。
这意味着VS Code的核心与特定的调试器完全解耦,这种架构使得VS Code可以调试任何东西,只要有可用的调试适配器,如下图所示:
观察与痛点
今天,有一大批满意的开发者定期使用VS Code进行调试,但作为我们使命的一部分,我们希望使调试变得更加容易,并让更多的开发者能够使用。
为此,我们开始进行对话,以更好地理解在VS Code中调试的痛点,并了解为什么一些开发者根本不使用我们的调试器。
以下是我们的观察结果:
调试配置很难做到正确
VS Code 是一个带有通用调试器的通用编辑器,并不针对特定的技术栈或运行时进行专门优化。因此,我们无法提供一个适用于所有人的默认调试配置。
这意味着VS Code需要您配置调试器的设置,并指定如何使用正确的参数等启动您的运行时。
我们认识到这可能很难做到正确,但我们没有看到一种方法可以为所有人完全消除调试配置。然而,我们确实相信调试配置可以简化,并且根据上下文,可以减少到最低限度。
我稍后会回到这个问题。
启动和附加配置之间的混淆
在VS Code中,我们有两个核心的调试概念:启动和附加,它们处理两种不同的工作流程和开发者群体。根据你的工作流程,可能会混淆哪种类型的配置适合你的项目。
如果你有浏览器开发者工具的背景,你可能不习惯“从你的工具启动”这个概念,因为你的浏览器实例已经打开了。当你打开开发者工具时,你只是将开发者工具附加到你已打开的浏览器标签上。另一方面,如果你有Java背景,你的编辑器为你启动Java进程,并且你的编辑器自动将其调试器附加到新启动的进程上,这是非常正常的。
解释launch和attach之间区别的最佳方式是,将launch configurations视为在VS Code附加到应用程序之前如何以调试模式启动应用程序的配方,而attach config则是如何将VS Code的调试器连接到已经运行的应用程序或进程的配方。
启动配置的价值在于,它们提供了一种方式,通过创建一个可重复且可与项目和团队共享的配置,来减轻使用正确的调试参数启动应用程序时的认知负担。
然而,当我们与开发者讨论他们如何启动应用程序时,我们发现了一个模式并做出了一个重要观察:
观察: 许多使用VS Code的开发者非常喜欢集成终端,并依赖命令行工具来启动他们的应用程序。对于许多人来说,在终端中运行命令然后从编辑器附加调试器是一种更自然的工作流程。这类似于在浏览器启动后打开开发者工具。
这一观察是关键,我们意识到许多用户并不希望在他们的编辑器中有一个完全“神奇”的启动体验。他们希望将编辑器保持为编辑和调试源代码的地方,并使用终端来启动应用程序、运行构建脚本等。这就是为什么我们在VS Code中提供集成终端体验的原因之一,因为我们相信一个功能良好的用户界面应该与终端共存并良好集成。
许多开发者不使用断点,因为他们正在检查状态变化
在观察开发者如何调试他们的应用程序时,我们还发现了另一个有趣的模式:使用日志记录而不是断点。
用于调试的日志记录并不是一个新概念,但观察非常重要:
观察: 传统的调试工作流程主要集中在减慢执行速度以检查程序逻辑,而日志记录工作流程通常涉及检查程序状态及其在应用程序正常执行期间的变化。这里的基本观察是,这两种技术用于不同的调试目的。
这一观察对于JavaScript开发者尤其相关,他们主要处理管理状态的复杂性,这可能解释了为什么大多数JavaScript开发者仍然更喜欢在他们的源代码中添加console.log而不是使用脚本调试器。
自动附加到Node进程
在反思一些开发者如何使用集成终端启动他们的调试会话时,我们发现了一个独特的机会。通过利用我们在VS Code中从您的编辑器和集成终端中获得的上下文信息,我们可以检测您的上下文并推断您调试的意图,这可以为Node.js开发者提供更简单的调试体验。
因此,在我们三月的VS Code迭代中,我们发布了一个名为Node的自动附加的新功能,该功能使Node调试器能够自动附加到从VS Code的集成终端以调试模式启动的Node.js进程。
您可以通过从命令面板运行Debug: Toggle Auto Attach命令来启用自动附加,一旦激活,您也可以从状态栏切换自动附加。
此功能完全消除了任何调试配置,因为我们将任何以node --inspect
启动的Node.js进程解释为调试意图。当与集成终端结合使用时,它提供了更简单的调试体验,允许开发者以自己的方式启动应用程序,同时消除了调试配置!🎉
NPM脚本和调试
许多Node.js开发者依赖npm脚本来启动应用程序或开始调试会话,我们在这方面也有一些好消息:自动附加也适用于npm脚本。如果你运行npm run debug
并且"debug"
脚本是"node --inspect"
或任何其他包含--inspect
的命令,那么自动附加将检测到并附加调试器🎉
我们还认识到,一些开发者希望有一种更直观的方式来查找和运行他们的npm脚本,因此在我们2018年4月的迭代中,我们添加了一个新的NPM脚本资源管理器,允许您直接从UI浏览和运行您的NPM脚本。作为简化调试配置工作的一部分,我们还使得可以直接从资源管理器启动Node.js调试,而无需创建调试配置。
如果你有一个包含调试参数(如--inspect
)的 npm 脚本,我们将自动检测并提供启动调试器的调试操作,如下所示:
介绍日志点
基于日志记录是一种重要的调试技术的学习,我们看到了一个机会,可以在我们现有的调试体验中添加状态检查。在VS Code的三月迭代中,我们发布了一个我们称之为Logpoints的调试功能的第一个实现。
日志点是一种断点变体,它不会“中断”进入调试器,而是将消息记录到控制台。
Logpoints的概念并不新鲜,过去几年中,我们在诸如Visual Studio、Edge DevTools和GDB等工具中看到了这个概念的不同版本,它们以Tracepoints和Logpoints等名称出现。
为什么以及何时使用日志点?
日志点基于这样的观察:在许多情况下,您不想在应用程序的特定部分停止执行,而是希望检查状态在应用程序生命周期中如何变化。
Logpoints 允许你在应用程序逻辑中“注入”按需日志记录语句,就像你在启动应用程序之前已经添加了日志记录语句一样。Logpoints 在执行时注入,并且不会持久化在源代码中,因此你不需要提前计划,而是可以根据需要注入 Logpoints。另一个好处是,你不需要担心在调试完成后清理源代码。
对于JavaScript开发者来说,这意味着你不再需要担心留下console.log
了——只需使用Logpoints!更好的是,你可以结合console.log
和Logpoints。如果你在已经有console.log
的源代码块中插入一个Logpoint,你将在调试控制台中看到这两种类型的日志语句。
云环境中的日志点
日志点在云环境(或任何远程环境)中特别有用,因为它们使您能够在无需重新部署应用程序的情况下将日志记录注入远程环境。同样重要的是,使用日志点不会停止脚本执行,因此与在常规断点上停止运行的应用程序不同,您的用户不会受到影响。
你可以阅读更多关于如何使用Azure上的Node.js的Logpoints的信息。
支持的语言
自从VS Code中首次发布Logpoints以来,我们已经看到越来越多的VS Code调试适配器采用它,如今以下语言已经支持Logpoint:
- Node.js 调试器
- Chrome 调试器
- Firefox 调试器
- Microsoft Edge 调试器
- React Native 调试器
- Python 调试器
- Dart 调试器
- Lua 调试器
- Java 调试器
- Debugger for Mainframe
VS Code 中的日志点
如果您有兴趣在VS Code的调试适配器中添加Logpoint支持,请查看协议中的这些更改。您还可以查看上述调试适配器,了解每个运行时如何选择实现Logpoints。
下一步
目前就这些,但我们还没有完成。在我们的七月迭代中,我们正在根据用户反馈改进自动附加功能,以提高可发现性(#53640)。
我们希望自动附加、NPM脚本资源管理器和日志点的引入将使使用VS Code进行调试变得更加容易。一如既往,我们渴望听到您的反馈,因此请在GitHub或Twitter上的@code联系我们。
代表VS Code团队:编程愉快!
/肯尼斯·奥肯伯格 - @auchenberg on Twitter