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