调试
Visual Studio Code 的主要功能之一是其强大的调试支持。VS Code 的内置调试器有助于加速编辑、编译和调试循环。
调试器扩展
VS Code 内置了对Node.js运行时的调试支持,可以调试 JavaScript、TypeScript 或任何其他转换为 JavaScript 的语言。
要调试其他语言和运行时(包括PHP、Ruby、Go、C#、Python、C++、PowerShell等),请在 VS Code Marketplace中查找扩展,或在顶级“运行”菜单中选择“安装其他调试器” 。Debuggers
以下是几个流行的扩展,其中包括调试支持:
提示:上面显示的扩展是动态查询的。选择上面的扩展程序图块以阅读说明和评论,以决定哪个扩展程序最适合您。
开始调试
以下文档基于内置Node.js调试器,但大多数概念和功能也适用于其他调试器。
在阅读有关调试的内容之前,首先创建一个示例 Node.js 应用程序会很有帮助。您可以按照Node.js 演练来安装 Node.js 并创建一个简单的“Hello World”JavaScript 应用程序 ( app.js
)。设置简单的应用程序后,此页面将引导您了解 VS Code 调试功能。
运行和调试视图
要打开“运行和调试”视图,请选择VS Code 一侧活动栏中的“运行和调试”图标。您还可以使用键盘快捷键⇧⌘D(Windows、Linux Ctrl+Shift+D)。
运行和调试视图显示与运行和调试相关的所有信息,并有一个包含调试命令和配置设置的顶栏。
如果尚未配置运行和调试(尚未launch.json
创建),VS Code 将显示 Run 启动视图。
运行菜单
顶级运行菜单包含最常见的运行和调试命令:
启动配置
要在 VS Code 中运行或调试简单的应用程序,请在“调试”开始视图上选择“运行并调试”或按F5,VS Code 将尝试运行当前活动的文件。
但是,对于大多数调试场景,创建启动配置文件是有益的,因为它允许您配置和保存调试设置详细信息。VS Code 将调试配置信息保存在launch.json
位于.vscode
工作区(项目根文件夹)的文件夹中或用户设置或工作区设置中的文件中。
要创建launch.json
文件,请单击运行启动视图中的创建 launch.json 文件链接。
VS Code 将尝试自动检测您的调试环境,但如果失败,您将必须手动选择它:
以下是为 Node.js 调试生成的启动配置:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}\\app.js"
}
]
}
如果返回到文件资源管理器视图 ( ⇧⌘E (Windows、Linux Ctrl+Shift+E ) ),您将看到 VS Code 已创建一个.vscode
文件夹并将launch.json
文件添加到您的工作区。
注意:即使没有在 VS Code 中打开文件夹,您也可以调试简单的应用程序,但无法管理启动配置和设置高级调试。如果您没有打开文件夹,则 VS Code 状态栏为紫色。
请注意,启动配置中可用的属性因调试器而异。您可以使用 IntelliSense 建议 ( ⌃Space (Windows、Linux Ctrl+Space ) ) 来找出特定调试器存在哪些属性。悬停帮助也适用于所有属性。
不要假设可用于一个调试器的属性也自动适用于其他调试器。如果您在启动配置中看到绿色波浪线,请将鼠标悬停在它们上方以了解问题所在,并在启动调试会话之前尝试修复它们。
检查所有自动生成的值并确保它们对您的项目和调试环境有意义。
启动与连接配置
在 VS Code 中,有两种核心调试模式:Launch和Attach,它们处理两种不同的工作流程和开发人员部分。根据您的工作流程,了解哪种类型的配置适合您的项目可能会令人困惑。
如果您来自浏览器开发人员工具背景,您可能不习惯“从工具启动”,因为您的浏览器实例已经打开。当您打开 DevTools 时,您只需将 DevTools附加到打开的浏览器选项卡即可。另一方面,如果您来自服务器或桌面背景,那么让编辑器为您启动进程是很正常的,并且编辑器会自动将其调试器附加到新启动的进程。
解释启动和附加之间差异的最佳方法是将启动配置视为如何在VS Code 附加到应用程序之前以调试模式启动应用程序的秘诀,而附加配置是如何连接 VS Code 的秘诀调试器到已运行的应用程序或进程。
VS Code 调试器通常支持在调试模式下启动程序或在调试模式下附加到已运行的程序。根据请求(attach
或launch
),需要不同的属性,VS Code 的launch.json
验证和建议应该对此有所帮助。
添加新配置
要将新配置添加到现有配置launch.json
,请使用以下技术之一:
- 如果光标位于配置数组内,请使用 IntelliSense。
- 按“添加配置”按钮以在数组开头调用片段 IntelliSense。
- 在“运行”菜单中选择“添加配置”选项。
VS Code 还支持复合启动配置,可同时启动多个配置;欲了解更多详情,请阅读本节。
为了启动调试会话,首先使用“运行和调试”视图中的“配置”下拉列表选择名为“启动程序”的配置。设置启动配置后,使用F5启动调试会话。
或者,您可以通过命令面板( ⇧⌘P (Windows、Linux Ctrl+Shift+P ) ) 过滤“调试:选择并开始调试”或键入'debug '
并选择要调试的配置来运行配置。
调试会话启动后,将显示“调试控制台”面板并显示调试输出,并且状态栏会更改颜色(默认颜色主题为橙色):
此外,调试状态会出现在状态栏中,显示活动的调试配置。通过选择调试状态,用户可以更改活动启动配置并开始调试,而无需打开“运行和调试”视图。
调试动作
调试会话启动后,调试工具栏将出现在编辑器的顶部。
行动 | 解释 |
---|---|
Continue / Pause F5 |
继续:恢复正常的程序/脚本执行(直到下一个断点)。 暂停:检查当前行执行的代码并逐行调试。 |
Step Over F10 |
将下一个方法作为单个命令执行,而不检查或遵循其组成步骤。 |
Step Into F11 |
输入下一个方法来逐行跟踪其执行。 |
Step Out ⇧F11 (Windows, Linux Shift+F11) |
在方法或子例程内部时,通过完成当前方法的剩余行返回到先前的执行上下文,就像它是单个命令一样。 |
Restart ⇧⌘F5 (Windows, Linux Ctrl+Shift+F5) |
终止当前程序执行并使用当前运行配置再次开始调试。 |
Stop ⇧F5 (Windows, Linux Shift+F5) |
终止当前程序的执行。 |
提示:使用该设置
debug.toolBarLocation
来控制调试工具栏的位置。它可以是默认的floating
、docked
运行和调试视图,或者hidden
。调试工具栏floating
可以水平拖动,也可以向下拖动到编辑器区域。
运行模式
除了调试程序之外,VS Code 还支持运行程序。调试:运行(启动而不调试)操作通过⌃F5(Windows、Linux Ctrl+F5)触发,并使用当前选择的启动配置。“运行”模式支持许多启动配置属性。VS Code 在程序运行时维护调试会话,按“停止”按钮终止程序。
提示:“运行”操作始终可用,但并非所有调试器扩展都支持“运行”。在这种情况下,“运行”将与“调试”相同。
断点
可以通过单击编辑器边距或在当前行上使用F9来切换断点。可以在“运行和调试”视图的“断点”部分中进行更精细的断点控制(启用/禁用/重新应用) 。
- 编辑器边距中的断点通常显示为红色实心圆圈。
- 禁用的断点有一个填充的灰色圆圈。
- 当调试会话启动时,无法向调试器注册的断点将变为灰色空心圆圈。如果在运行没有实时编辑支持的调试会话时编辑源代码,也可能会发生同样的情况。
如果调试器支持中断不同类型的错误或异常,则这些也将在BREAKPOINTS视图中可用。
重新应用所有断点命令将所有断点再次设置到其原始位置。如果您的调试环境“懒惰”并且在尚未执行的源代码中“放错了”断点,这会很有帮助。
或者,可以通过启用以下设置在编辑器的概述标尺中显示断点debug.showBreakpointsInOverviewRuler
:
日志点
日志点是断点的变体,它不会“中断”调试器,而是将消息记录到控制台。日志点对于在调试无法暂停或停止的生产服务器时注入日志记录特别有用。
日志点由“菱形”形状的图标表示。日志消息是纯文本,但可以包含要在大括号 ('{}') 内计算的表达式。
就像常规断点一样,日志点可以启用或禁用,也可以通过条件和/或命中计数进行控制。
注意:VS Code 的内置 Node.js 调试器支持日志点,但也可以通过其他调试扩展来实现。例如,Python 和 Java 扩展支持日志点。
数据检查
可以在运行和调试视图的变量部分或通过将鼠标悬停在编辑器中的源代码上来检查变量。变量值和表达式求值与CALL STACK部分中选定的堆栈帧相关。
可以使用变量上下文菜单中的“设置值”操作来修改变量值。此外,您可以使用“复制值”操作来复制变量的值,或使用“复制为表达式”操作来复制表达式以访问变量。
还可以在“运行”和“调试”视图的“观察”部分中计算和观察变量和表达式。
当焦点位于变量部分时,可以通过键入来过滤变量名称和值。
Launch.json 属性
有许多launch.json
属性可以帮助支持不同的调试器和调试场景。如上所述,在指定属性值后,您可以使用 IntelliSense ( ⌃Space (Windows、Linux Ctrl+Space ) ) 查看可用属性的列表type
。
以下属性对于每个启动配置都是必需的:
type
- 用于此启动配置的调试器类型。每个安装的调试扩展都会引入一种类型:node
例如,对于内置 Node 调试器,或者php
对于go
PHP 和 Go 扩展。request
- 此启动配置的请求类型。目前,launch
和attach
均受支持。name
- 显示在“调试启动配置”下拉列表中的易于阅读的名称。
以下是一些适用于所有启动配置的可选属性:
presentation
- 使用对象中的order
、group
和hidden
属性presentation
,您可以在调试配置下拉列表和调试快速选择中对配置和复合进行排序、分组和隐藏。preLaunchTask
- 要在调试会话开始之前启动任务,请将此属性设置为tasks.json(在工作区的.vscode
文件夹中)中指定的任务的标签。或者,可以将其设置${defaultBuildTask}
为使用默认构建任务。postDebugTask
- 要在调试会话最后启动任务,请将此属性设置为tasks.json(在工作区的.vscode
文件夹中)中指定的任务名称。internalConsoleOptions
- 此属性控制调试会话期间调试控制台面板的可见性。debugServer
-仅适用于调试扩展作者:此属性允许您连接到指定端口,而不是启动调试适配器。serverReadyAction
- 如果您想在调试中的程序向调试控制台或集成终端输出特定消息时在 Web 浏览器中打开 URL。有关详细信息,请参阅下面的调试服务器程序时自动打开 URI部分。
许多调试器支持以下一些属性:
program
- 启动调试器时要运行的可执行文件或文件args
- 传递给程序进行调试的参数env
- 环境变量(该值null
可用于“取消定义”变量)envFile
- 带有环境变量的 dotenv 文件的路径cwd
- 用于查找依赖项和其他文件的当前工作目录port
- 连接到正在运行的进程时的端口stopOnEntry
- 程序启动时立即中断console
- 使用哪种类型的控制台,例如internalConsole
、integratedTerminal
或externalTerminal
变量替换
VS Code 使常用路径和其他值可用作变量,并支持launch.json
. 这意味着您不必在调试配置中使用绝对路径。例如,${workspaceFolder}
给出工作区文件夹的根路径、${file}
在活动编辑器中打开的文件以及${env:Name}
环境变量“名称”。您可以在变量参考中或通过在字符串属性中调用 IntelliSense来查看预定义变量的完整列表launch.json
。
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"cwd": "${workspaceFolder}",
"args": ["${env:USERNAME}"]
}
特定于平台的属性
Launch.json
支持定义取决于运行调试器的操作系统的值(例如,要传递给程序的参数)。为此,请将特定于平台的文字放入文件中launch.json
,并在该文字内指定相应的属性。
"args"
下面是在 Windows 上以不同方式传递给程序的示例:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulpfile.js",
"args": ["myFolder/path/app.js"],
"windows": {
"args": ["myFolder\\path\\app.js"]
}
}
]
}
有效的操作属性适用"windows"
于 Windows、"linux"
Linux 和"osx"
macOS。在操作系统特定范围内定义的属性会覆盖在全局范围内定义的属性。
请注意,该type
属性不能放置在特定于平台的部分内,因为type
间接确定远程调试场景中的平台,这将导致循环依赖。
在下面的示例中,除 macOS 外,调试程序始终在进入时停止:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulpfile.js",
"stopOnEntry": true,
"osx": {
"stopOnEntry": false
}
}
]
}
全局启动配置
"launch"
VS Code 支持在用户设置中添加对象。然后,此"launch"
配置将在您的工作区之间共享。例如:
"launch": {
"version": "0.2.0",
"configurations": [{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${file}"
}]
}
高级断点主题
条件断点
强大的 VS Code 调试功能是能够根据表达式、命中计数或两者的组合设置条件。
- 表达式条件:只要表达式的计算结果为,就会命中断点
true
。 - 命中计数:“命中计数”控制断点在“中断”执行之前需要命中多少次。是否尊重“命中计数”以及表达式的确切语法因调试器扩展而异。
您可以在创建源断点(使用“添加条件断点”操作)或修改现有断点(使用“编辑条件”操作)时添加条件和/或命中计数。在这两种情况下,都会打开一个带有下拉菜单的内联文本框,您可以在其中输入表达式:
函数断点和异常断点还支持条件和命中计数编辑支持。您可以从上下文菜单或新的内联编辑条件操作启动条件编辑。
BREAKPOINTS视图中的条件编辑示例:
如果调试器不支持条件断点,则“添加条件断点”和“编辑条件”操作将丢失。
内联断点
仅当执行到达与内联断点关联的列时,才会命中内联断点。这在调试单行中包含多个语句的精简代码时特别有用。
可以使用⇧F9(Windows、Linux Shift+F9)或在调试会话期间通过上下文菜单设置内联断点。内联断点在编辑器中内联显示。
内联断点也可以有条件。可以通过编辑器左边距中的上下文菜单编辑一行上的多个断点。
函数断点
调试器可以支持通过指定函数名称来创建断点,而不是直接在源代码中放置断点。这在源不可用但函数名称已知的情况下非常有用。
通过按BREAKPOINTS部分标题中的+按钮并输入函数名称来创建函数断点。函数断点在BREAKPOINTS部分中以红色三角形显示。
数据断点
如果调试器支持数据断点,则可以从VARIABLES视图的上下文菜单中设置它们。值更改/读取/访问时中断命令将添加一个数据断点,当基础变量的值更改/读取/访问时会命中该断点。数据断点在“断点”部分中以红色六边形显示。
调试控制台 REPL
可以使用调试控制台REPL(读取-求值-打印循环)功能来计算表达式。要打开调试控制台,请使用“调试”窗格顶部的“调试控制台”操作或使用“查看:调试控制台”命令 ( ⇧⌘Y (Windows、Linux Ctrl+Shift+Y ) )。按Enter 键后将对表达式求值,并且调试控制台 REPL 在您键入时显示建议。如果需要输入多行,请在各行之间使用Shift+Enter,然后使用Enter发送所有行进行评估。调试控制台输入使用活动编辑器的模式,这意味着调试控制台输入支持语法着色、缩进、自动关闭引号和其他语言功能。
注意:您必须处于正在运行的调试会话中才能使用调试控制台 REPL。
将输入/输出重定向到调试目标/从调试目标重定向输入/输出
重定向输入/输出是调试器/运行时特定的,因此 VS Code 没有适用于所有调试器的内置解决方案。
您可能需要考虑以下两种方法:
-
在终端或命令提示符中手动启动程序进行调试(“调试目标”),并根据需要重定向输入/输出。确保将适当的命令行选项传递给调试目标,以便调试器可以附加到它。创建并运行附加到调试目标的“附加”调试配置。
-
如果您使用的调试器扩展可以在 VS Code 的集成终端(或外部终端)中运行调试目标,则可以尝试将 shell 重定向语法(例如“<”或“">”)作为参数传递。
这是一个launch.json
配置示例:
{
"name": "launch program that reads a file from stdin",
"type": "node",
"request": "launch",
"program": "program.js",
"console": "integratedTerminal",
"args": ["<", "in.txt"]
}
此方法要求“<”语法通过调试器扩展传递,并且最终在集成终端中未经修改。
多目标调试
对于涉及多个进程(例如客户端和服务器)的复杂场景,VS Code 支持多目标调试。
使用多目标调试很简单:启动第一个调试会话后,您可以启动另一个会话。一旦第二个会话启动并运行,VS Code UI 就会切换到多目标模式:
- 各个会话现在在CALL STACK视图中显示为顶级元素。
- 调试工具栏显示当前活动的会话(所有其他会话都在下拉菜单中可用)。
- 调试操作(例如,调试工具栏中的所有操作)在活动会话上执行。可以通过使用调试工具栏中的下拉菜单或在“调用堆栈”视图中选择不同的元素来更改活动会话。
复合发射配置
启动多个调试会话的另一种方法是使用复合启动配置。复合启动配置列出了应并行启动的两个或多个启动配置的名称。(可选)preLaunchTask
可以指定在启动各个调试会话之前运行。布尔标志stopAll
控制手动终止一个会话是否会停止所有复合会话。
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Server",
"program": "${workspaceFolder}/server.js"
},
{
"type": "node",
"request": "launch",
"name": "Client",
"program": "${workspaceFolder}/client.js"
}
],
"compounds": [
{
"name": "Server/Client",
"configurations": ["Server", "Client"],
"preLaunchTask": "${defaultBuildTask}",
"stopAll": true
}
]
}
复合启动配置显示在启动配置下拉菜单中。
远程调试
VS Code 本身不支持远程调试:这是您正在使用的调试扩展的一项功能,您应该咨询Marketplace中的扩展页面以获取支持和详细信息。
不过,有一个例外:VS Code 中包含的 Node.js 调试器支持远程调试。请参阅Node.js 调试主题以了解如何配置它。
调试服务器程序时自动打开URI
开发 Web 程序通常需要在 Web 浏览器中打开特定的 URL,以便在调试器中命中服务器代码。VS Code 有一个内置功能“ serverReadyAction ”来自动执行此任务。
下面是一个简单的Node.js Express应用程序的示例:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.send('Hello World!');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
该应用程序首先为“/”URL 安装“Hello World”处理程序,然后开始侦听端口 3000 上的 HTTP 连接。该端口在调试控制台中公布,通常,开发人员现在会在其浏览器应用程序中键入内容http://localhost:3000
。
serverReadyAction功能可以将结构化属性添加到任何启动配置并serverReadyAction
选择要执行的“操作”:
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"serverReadyAction": {
"pattern": "listening on port ([0-9]+)",
"uriFormat": "http://localhost:%s",
"action": "openExternally"
}
}
这里的pattern
属性描述了用于匹配宣布端口的程序输出字符串的正则表达式。端口号的模式放入括号中,以便它可用作正则表达式捕获组。在此示例中,我们仅提取端口号,但也可以提取完整的 URI。
该uriFormat
属性描述了如何将端口号转换为 URI。第一个%s
被匹配模式的第一个捕获组替换。
然后,使用为 URI 方案配置的标准应用程序在 VS Code 外部(“外部”)打开生成的 URI。
通过 Edge 或 Chrome 触发调试
或者,action
可以将 设定为debugWithEdge
或debugWithChrome
。在此模式下,webRoot
可以添加传递到 Chrome 或 Edge 调试会话的属性。
为了稍微简化一下,大多数属性都是可选的,我们使用以下后备值:
- pattern:
"listening on.* (https?://\\S+|[0-9]+)"
匹配常用的消息“正在监听端口 3000”或“正在监听:https://localhost:5001”。 - uri格式:
"http://localhost:%s"
- 网络根目录:
"${workspaceFolder}"
触发任意启动配置
在某些情况下,您可能需要为浏览器调试会话配置其他选项,或者完全使用不同的调试器。action
您可以通过将startDebugging
属性设置为匹配name
时启动的启动配置的名称来执行此操作。pattern
指定的启动配置必须与serverReadyAction
.
这里是serverReadyAction功能的实际应用:
下一步
要了解 VS Code 的 Node.js 调试支持,请查看:
- Node.js - 描述 Node.js 调试器,它包含在 VS Code 中。
- TypeScript - Node.js 调试器还支持 TypeScript 调试。
要查看有关 Node.js 调试基础知识的教程,请观看以下视频:
- 介绍视频 - 调试- 展示调试的基础知识。
- Node.js 调试入门- 展示如何将调试器附加到正在运行的 Node.js 进程。
要了解通过 VS Code 扩展对其他编程语言的调试支持:
要了解 VS Code 的任务运行支持,请访问:
- 任务- 描述如何使用 Gulp、Grunt 和 Jake 运行任务以及如何显示错误和警告。
要编写您自己的调试器扩展,请访问:
- 调试器扩展- 使用模拟示例来说明创建 VS Code 调试扩展所需的步骤。
常见问题
支持哪些调试场景?
使用 VS Code 在 Linux、macOS 和 Windows 上开箱即用地支持基于 Node.js 的应用程序的调试。Marketplace 中提供的VS Code 扩展支持许多其他场景。
我在“运行和调试”视图下拉列表中没有看到任何启动配置。怎么了?
最常见的问题是您没有设置launch.json
或者该文件中存在语法错误。或者,您可能需要打开一个文件夹,因为无文件夹调试不支持启动配置。