通过任务集成外部工具
有许多工具可以自动化诸如 linting、构建、打包、测试或部署软件系统等任务。示例包括 TypeScript 编译器,像 ESLint 和 TSLint 这样的代码检查工具,以及像 Make、Ant、Gulp、Jake、Rake 和 MSBuild 这样的构建系统。

这些工具主要通过命令行运行,并自动化内部和外部软件开发循环(编辑、编译、测试和调试)中的工作。鉴于它们在开发生命周期中的重要性,能够在 VS Code 中运行工具并分析其结果是非常有用的。VS Code 中的任务可以配置为运行脚本和启动进程,这样许多现有工具就可以在 VS Code 中使用,而无需输入命令行或编写新代码。工作区或文件夹特定的任务在工作区的 .vscode 文件夹中的 tasks.json 文件中配置。
扩展还可以使用 任务提供者 贡献任务,并且这些贡献的任务可以添加在 tasks.json 文件中定义的工作区特定配置。
注意: 任务支持仅在处理工作区文件夹时可用。在编辑单个文件时不可用。
TypeScript Hello World
让我们从一个简单的“Hello World”TypeScript 程序开始,我们希望将其编译为 JavaScript。
创建一个空文件夹“mytask”,生成一个 tsconfig.json 文件,并从该文件夹启动 VS Code。
mkdir mytask
cd mytask
tsc --init
code .
现在创建一个包含以下内容的 HelloWorld.ts 文件
function sayHello(name: string): void {
console.log(`Hello ${name}!`);
}
sayHello('Dave');
按下 ⇧⌘B (Windows, Linux Ctrl+Shift+B) 或从全局 终端 菜单运行 运行构建任务 会显示以下选择器

第一个条目执行 TypeScript 编译器并将 TypeScript 文件转换为 JavaScript 文件。当编译器完成时,应该会有一个 HelloWorld.js 文件。第二个条目以监视模式启动 TypeScript 编译器。每次保存 HelloWorld.ts 文件都会重新生成 HelloWorld.js 文件。
您还可以将 TypeScript 构建或监视任务定义为默认构建任务,这样它就会在触发 运行构建任务 (⇧⌘B (Windows, Linux Ctrl+Shift+B)) 时直接执行。为此,请从全局 终端 菜单中选择 配置默认构建任务。这会显示一个包含可用构建任务的选择器。选择 tsc: build 或 tsc: watch,VS Code 将生成一个 tasks.json 文件。下面显示的文件将 tsc: build 任务设为默认构建任务
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"problemMatcher": ["$tsc"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
上面 tasks.json 示例没有定义新任务。它只是将 VS Code 的 TypeScript 扩展贡献的 tsc: build 任务标记为默认构建任务。您现在可以通过按下 ⇧⌘B (Windows, Linux Ctrl+Shift+B) 来执行 TypeScript 编译器。
任务自动检测
VS Code 目前自动检测 Gulp、Grunt、Jake 和 npm 的任务。我们正在与相应的扩展作者合作,以增加对 Maven 和 C# dotnet 命令的支持。如果您使用 Node.js 作为运行时开发 JavaScript 应用程序,您通常会有一个 package.json 文件来描述您的依赖项和要运行的脚本。如果您克隆了 eslint-starter 示例,那么从全局菜单执行 运行任务 会显示以下列表

如果您尚未安装,请运行 npm install 安装必要的 npm 模块。现在打开 server.js 文件并在语句末尾添加一个分号(请注意 ESLint starter 假定语句没有分号)并再次执行 运行任务。这次选择 npm: lint 任务。当提示要使用的问题匹配器时,选择 ESLint stylish

执行任务会产生一个错误,显示在 问题 视图中

此外,VS Code 创建了一个包含以下内容的 tasks.json 文件
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "lint",
"problemMatcher": ["$eslint-stylish"]
}
]
}
这指示 VS Code 使用 ESLint stylish 格式扫描 npm lint 脚本的输出以查找问题。
对于 Gulp、Grunt 和 Jake,任务自动检测的工作方式相同。下面是为 vscode-node-debug 扩展检测到的任务示例。

提示: 您可以通过 快速打开 (⌘P (Windows, Linux Ctrl+P)) 键入 'task'、空格 和命令名称来运行您的任务。在本例中,是 'task lint'。
任务自动检测可以使用以下设置禁用
{
"typescript.tsc.autoDetect": "off",
"grunt.autoDetect": "off",
"jake.autoDetect": "off",
"gulp.autoDetect": "off",
"npm.autoDetect": "off"
}
自定义任务
并非所有任务或脚本都可以在您的工作区中自动检测到。有时需要定义自己的自定义任务。假设您有一个脚本来运行您的测试以正确设置一些环境。该脚本存储在您的工作区内的脚本文件夹中,Linux 和 macOS 下命名为 test.sh,Windows 下命名为 test.cmd。从全局 终端 菜单运行 配置任务 并选择 从模板创建 tasks.json 文件 条目。这会打开以下选择器

注意: 如果您没有看到任务运行器模板列表,您的文件夹中可能已经有一个
tasks.json文件,并且其内容将在编辑器中打开。关闭该文件,并为了本示例删除或重命名它。
我们正在开发更多的自动检测支持,所以这个列表将来会越来越短。由于我们要编写自己的自定义任务,请从列表中选择 其他。这会打开一个带有任务骨架的 tasks.json 文件。将其内容替换为以下内容
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Run tests",
"type": "shell",
"command": "./scripts/test.sh",
"windows": {
"command": ".\\scripts\\test.cmd"
},
"group": "test",
"presentation": {
"reveal": "always",
"panel": "new"
}
}
]
}
任务的属性具有以下语义
- label:在用户界面中使用的任务标签。
- type:任务类型。对于自定义任务,可以是
shell或process。如果指定shell,则命令被解释为 shell 命令(例如:bash、cmd 或 PowerShell)。如果指定process,则命令被解释为要执行的进程。 - command:要执行的实际命令。
- windows:任何 Windows 特定的属性。当命令在 Windows 操作系统上执行时,将使用这些属性而不是默认属性。
- group:定义任务所属的组。在本例中,它属于
test组。属于测试组的任务可以通过从 命令面板 运行 运行测试任务 来执行。 - presentation:定义在用户界面中如何处理任务输出。在此示例中,显示输出的集成终端将
始终显示,并且每次任务运行都会创建一个新终端。 - options:覆盖
cwd(当前工作目录)、env(环境变量)或shell(默认 shell)的默认值。选项可以按任务设置,也可以全局或按平台设置。此处配置的环境变量只能在您的任务脚本或进程中引用,如果它们是您的参数、命令或其他任务属性的一部分,则不会被解析。 - runOptions:定义任务何时以及如何运行。
- hide:在“运行任务快速选择”中隐藏任务,这对于复合任务中不能独立运行的元素很有用。
您可以在 tasks.json 文件中使用 IntelliSense 查看完整的任务属性和值。使用 触发建议 (⌃Space (Windows, Linux Ctrl+Space)) 调出建议,并将鼠标悬停在上面或通过 阅读更多... ('i') 弹出窗口阅读描述。

您还可以查看 tasks.json 架构。
当命令和参数包含空格或其他特殊字符(如 $)时,Shell 命令需要特殊处理。默认情况下,任务系统支持以下行为
- 如果提供单个命令,任务系统会将命令按原样传递给底层 shell。如果命令需要引号或转义才能正常工作,则命令需要包含适当的引号或转义字符。例如,要列出名称中包含空格的文件夹的目录,在 bash 中执行的命令应如下所示:
ls 'folder with spaces'。
{
"label": "dir",
"type": "shell",
"command": "dir 'folder with spaces'"
}
- 如果提供了命令和参数,如果命令或参数包含空格,任务系统将使用单引号。对于
cmd.exe,使用双引号。像下面这样的 shell 命令将在 PowerShell 中作为dir 'folder with spaces'执行。
{
"label": "dir",
"type": "shell",
"command": "dir",
"args": ["folder with spaces"]
}
- 如果您想控制参数的引用方式,参数可以是指定值和引用样式的字面量。下面的示例对包含空格的参数使用转义而不是引用。
{
"label": "dir",
"type": "shell",
"command": "dir",
"args": [
{
"value": "folder with spaces",
"quoting": "escape"
}
]
}
除了转义,还支持以下值
- strong:使用 shell 的强引用机制,它抑制字符串中的所有评估。在 PowerShell 和 Linux 及 macOS 下的 shell 中,使用单引号 (
')。对于 cmd.exe,使用"。 - weak:使用 shell 的弱引用机制,它仍然评估字符串中的表达式(例如,环境变量)。在 PowerShell 和 Linux 及 macOS 下的 shell 中,使用双引号 (
")。cmd.exe 不支持弱引用,所以 VS Code 也使用"。
如果命令本身包含空格,VS Code 默认也会对命令进行强引用。与参数一样,用户可以使用相同的字面样式控制命令的引用。
还有更多任务属性可以配置您的工作流程。您可以使用 IntelliSense 和 ⌃Space (Windows, Linux Ctrl+Space) 来获取有效属性的概述。

除了全局菜单栏,任务命令还可以通过 命令面板 (⇧⌘P (Windows, Linux Ctrl+Shift+P)) 访问。您可以筛选“任务”并查看各种与任务相关的命令。

复合任务
您还可以使用 dependsOn 属性将更简单的任务组合成复合任务。例如,如果您有一个包含客户端和服务器文件夹的工作区,并且两者都包含构建脚本,您可以创建一个任务,在单独的终端中启动这两个构建脚本。如果在 dependsOn 属性中列出多个任务,它们默认会并行执行。
tasks.json 文件如下所示
{
"version": "2.0.0",
"tasks": [
{
"label": "Client Build",
"command": "gulp",
"args": ["build"],
"options": {
"cwd": "${workspaceFolder}/client"
}
},
{
"label": "Server Build",
"command": "gulp",
"args": ["build"],
"options": {
"cwd": "${workspaceFolder}/server"
}
},
{
"label": "Build",
"dependsOn": ["Client Build", "Server Build"]
}
]
}
如果您指定 "dependsOrder": "sequence",那么您的任务依赖项将按照它们在 dependsOn 中列出的顺序执行。在 dependsOn 中使用 "dependsOrder": "sequence" 的任何后台/监视任务都必须有一个问题匹配器,用于跟踪它们何时“完成”。以下任务将运行任务二、任务三,然后是任务一。
{
"label": "One",
"type": "shell",
"command": "echo Hello ",
"dependsOrder": "sequence",
"dependsOn": ["Two", "Three"]
}
用户级别任务
您可以使用 任务:打开用户任务 命令创建不与特定工作区或文件夹绑定的用户级别任务。这里只能使用 shell 和 process 任务,因为其他任务类型需要工作区信息。
输出行为
有时您想控制集成终端面板在运行任务时的行为。例如,您可能想最大化编辑器空间,只在您认为有问题时才查看任务输出。终端的行为可以通过任务的 presentation 属性来控制。它提供以下属性
- reveal:控制集成终端面板是否显示在前。有效值为
always- 面板始终显示在前。这是默认值。never- 用户必须使用 视图 > 终端 命令 (⌃` (Windows, Linux Ctrl+`)) 显式地将终端面板带到前面。silent- 只有在输出未扫描错误和警告时,终端面板才会显示在前。
- revealProblems:控制运行此任务时是否显示“问题”面板。优先于选项
reveal。默认值为never。always- 执行此任务时始终显示“问题”面板。onProblem- 仅在发现问题时才显示“问题”面板。never- 执行此任务时从不显示“问题”面板。
- focus:控制终端是否获取输入焦点。默认值为
false。 - echo:控制执行的命令是否在终端中回显。默认值为
true。 - showReuseMessage:控制是否显示“终端将被任务重用,按任意键关闭”消息。
- panel:控制终端实例是否在任务运行之间共享。可能的值是
shared- 终端是共享的,其他任务运行的输出会添加到同一个终端。dedicated- 终端专用于特定任务。如果该任务再次执行,则会重用该终端。但是,不同任务的输出会在不同的终端中显示。new- 该任务的每次执行都使用一个新的干净终端。
- clear:控制在运行此任务之前是否清除终端。默认值为
false。 - close:控制任务退出时是否关闭运行任务的终端。默认值为
false。 - group:控制任务是否在特定的终端组中使用分割窗格执行。同一组(由字符串值指定)中的任务将使用分割终端进行显示,而不是新的终端面板。
您也可以修改自动检测任务的终端面板行为。例如,如果您想更改上面 ESLint 示例中 npm: run lint 的输出行为,请为其添加 presentation 属性
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "lint",
"problemMatcher": ["$eslint-stylish"],
"presentation": {
"reveal": "never"
}
}
]
}
您还可以将自定义任务与检测到的任务的配置混合使用。一个配置 npm: run lint 任务并添加自定义 运行测试 任务的 tasks.json 如下所示
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "lint",
"problemMatcher": ["$eslint-stylish"],
"presentation": {
"reveal": "never"
}
},
{
"label": "Run tests",
"type": "shell",
"command": "./scripts/test.sh",
"windows": {
"command": ".\\scripts\\test.cmd"
},
"group": "test",
"presentation": {
"reveal": "always",
"panel": "new"
}
}
]
}
运行行为
您可以使用 runOptions 属性指定任务的运行行为
- reevaluateOnRerun:控制通过 重新运行上次任务 命令执行任务时变量的评估方式。默认值为
true,这意味着任务重新运行时变量将重新评估。当设置为false时,将使用上次运行任务时解析的变量值。 - runOn:指定任务何时运行。
default- 任务只会在通过 运行任务 命令执行时运行。folderOpen- 任务将在包含文件夹打开时运行。您第一次打开包含folderOpen任务的文件夹时,系统会询问您是否允许任务在该文件夹中自动运行。您以后可以使用 管理自动任务 命令并选择 允许自动任务 和 禁止自动任务 来更改您的决定。
- instanceLimit - 允许同时运行的任务实例数。默认值为
1。
自定义自动检测任务
如上所述,您可以在 tasks.json 文件中自定义自动检测的任务。您通常会这样做是为了修改演示属性或附加问题匹配器以扫描任务的输出以查找错误和警告。您可以通过按 运行任务 列表右侧的齿轮图标来直接从列表中自定义任务,以将相应的任务引用插入到 tasks.json 文件中。假设您有以下 Gulp 文件使用 ESLint(该文件取自 https://github.com/adametry/gulp-eslint)来检查 JavaScript 文件
const gulp = require('gulp');
const eslint = require('gulp-eslint');
gulp.task('lint', () => {
// ESLint ignores files with "node_modules" paths.
// So, it's best to have gulp ignore the directory as well.
// Also, Be sure to return the stream from the task;
// Otherwise, the task may end before the stream has finished.
return (
gulp
.src(['**/*.js', '!node_modules/**'])
// eslint() attaches the lint output to the "eslint" property
// of the file object so it can be used by other modules.
.pipe(eslint())
// eslint.format() outputs the lint results to the console.
// Alternatively use eslint.formatEach() (see Docs).
.pipe(eslint.format())
// To have the process exit with an error code (1) on
// lint error, return the stream and pipe to failAfterError last.
.pipe(eslint.failAfterError())
);
});
gulp.task('default', ['lint'], function() {
// This will only run if the lint task is successful...
});
从全局 终端 菜单执行 运行任务 将显示以下选择器

按下齿轮图标。这将创建以下 tasks.json 文件
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "gulp",
"task": "default",
"problemMatcher": []
}
]
}
通常,您现在会添加一个问题匹配器(在本例中为 $eslint-stylish)或修改演示设置。
使用问题匹配器处理任务输出
VS Code 可以使用问题匹配器处理任务的输出。问题匹配器会扫描任务输出文本中已知的警告或错误字符串,并在编辑器和“问题”面板中以内联方式报告这些问题。VS Code 内置了几个问题匹配器
- TypeScript:
$tsc假定输出中的文件名是相对于打开文件夹的。 - TypeScript Watch:
$tsc-watch匹配tsc编译器在监视模式下执行时报告的问题。 - JSHint:
$jshint假定文件名报告为绝对路径。 - JSHint Stylish:
$jshint-stylish假定文件名报告为绝对路径。 - ESLint Compact:
$eslint-compact假定输出中的文件名是相对于打开文件夹的。 - ESLint Stylish:
$eslint-stylish假定输出中的文件名是相对于打开文件夹的。 - Go:
$go匹配go编译器报告的问题。假定文件名是相对于打开文件夹的。 - CSharp 和 VB 编译器:
$mscompile假定文件名报告为绝对路径。 - Lessc 编译器:
$lessc假定文件名报告为绝对路径。 - Node Sass 编译器:
$node-sass假定文件名报告为绝对路径。
您还可以创建自己的问题匹配器,我们将在 后面一节 中讨论。
将键盘快捷键绑定到任务
如果您需要频繁运行某个任务,可以为该任务定义一个键盘快捷键。
例如,要将 Ctrl+H 绑定到上面的 运行测试 任务,请将以下内容添加到您的 keybindings.json 文件中
{
"key": "ctrl+h",
"command": "workbench.action.tasks.runTask",
"args": "Run tests"
}
变量替换
在编写任务配置时,拥有一组预定义的常用变量(例如活动文件 (${file}) 或工作区根文件夹 (${workspaceFolder}))非常有用。VS Code 支持 tasks.json 文件中字符串内的变量替换,您可以在 变量参考 中查看预定义变量的完整列表。
注意: 并非所有属性都接受变量替换。具体来说,只有
command、args和options支持变量替换。
以下是一个自定义任务配置的示例,它将当前打开的文件传递给 TypeScript 编译器。
{
"label": "TypeScript compile",
"type": "shell",
"command": "tsc ${file}",
"problemMatcher": ["$tsc"]
}
同样,您可以通过在名称前加上 ${config: 来引用项目的配置设置。例如,${config:python.formatting.autopep8Path} 返回 Python 扩展设置 formatting.autopep8Path。
以下是一个自定义任务配置的示例,它使用由 python.formatting.autopep8Path 设置定义的 autopep8 可执行文件对当前文件执行 autopep8
{
"label": "autopep8 current file",
"type": "process",
"command": "${config:python.formatting.autopep8Path}",
"args": ["--in-place", "${file}"]
}
如果您想指定 Python 扩展用于 tasks.json 或 launch.json 的选定 Python 解释器,您可以使用 ${command:python.interpreterPath} 命令。
如果简单的变量替换还不够,您还可以通过在 tasks.json 文件中添加 inputs 部分来从任务用户那里获取输入。

有关 inputs 的更多信息,请参阅 变量参考。
操作系统特定属性
任务系统支持定义特定于操作系统的值(例如,要执行的命令)。为此,请在 tasks.json 文件中放置一个操作系统特定的字面量,并在该字面量中指定相应的属性。
以下是一个示例,它使用 Node.js 可执行文件作为命令,并且在 Windows 和 Linux 上的处理方式不同
{
"label": "Run Node",
"type": "process",
"windows": {
"command": "C:\\Program Files\\nodejs\\node.exe"
},
"linux": {
"command": "/usr/bin/node"
}
}
有效的操作系统属性有:Windows 的 windows,Linux 的 linux,以及 macOS 的 osx。在操作系统特定范围内定义的属性会覆盖在任务或全局范围内定义的属性。
全局任务
任务属性也可以在全局范围内定义。如果存在,它们将用于特定任务,除非它们使用不同的值定义了相同的属性。在下面的示例中,有一个全局 presentation 属性,它定义了所有任务都应该在一个新面板中执行
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"presentation": {
"panel": "new"
},
"tasks": [
{
"label": "TS - Compile current file",
"type": "shell",
"command": "tsc ${file}",
"problemMatcher": ["$tsc"]
}
]
}
提示: 要访问全局范围的
tasks.json文件,请打开命令面板 (⇧⌘P (Windows, Linux Ctrl+Shift+P)) 并运行 任务:打开用户任务 命令。
PowerShell 中的字符转义
当默认 shell 是 PowerShell,或者当任务配置为使用 PowerShell 时,您可能会看到意外的空格和引号转义。意外的转义只发生在 cmdlet 中,因为 VS Code 不知道您的命令是否包含 cmdlet。下面的示例 1 显示了一个您会得到不适用于 PowerShell 的转义的情况。示例 2 显示了获得良好转义的最佳跨平台方式。在某些情况下,您可能无法遵循示例 2,您需要进行示例 3 中所示的手动转义。
"tasks": [
{
"label": "PowerShell example 1 (unexpected escaping)",
"type": "shell",
"command": "Get-ChildItem \"Folder With Spaces\""
},
{
"label": "PowerShell example 2 (expected escaping)",
"type": "shell",
"command": "Get-ChildItem",
"args": ["Folder With Spaces"]
},
{
"label": "PowerShell example 3 (manual escaping)",
"type": "shell",
"command": "& Get-ChildItem \\\"Folder With Spaces\\\""
}
]
更改任务输出的编码
任务经常处理磁盘上的文件。如果这些文件以与系统编码不同的编码存储在磁盘上,您需要让作为任务执行的命令知道要使用哪种编码。由于这取决于操作系统和所使用的 shell,因此没有通用的解决方案来控制它。以下是关于如何使其工作的建议和示例。
如果您需要调整编码,您应该检查更改操作系统使用的默认编码是否合理,或者至少通过调整 shell 的配置文件来更改您使用的 shell 的编码。
如果您只需要为特定任务调整它,那么将更改编码所需的操作系统特定命令添加到任务命令行。以下示例适用于 Windows,默认代码页为 437。该任务显示包含西里尔字符的文件的输出,因此需要代码页 866。假定默认 shell 设置为 cmd.exe,列出文件的任务如下所示
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "more",
"type": "shell",
"command": "chcp 866 && more russian.txt",
"problemMatcher": []
}
]
}
如果在 PowerShell 中执行任务,命令需要写成 chcp 866; more russian.txt。在 Linux 和 macOS 上,可以使用 locale 命令来检查区域设置并调整必要的环境变量。
任务运行示例
为了突出任务的强大功能,这里有一些 VS Code 如何使用任务集成外部工具(如 linting 和编译器)的示例。
将 TypeScript 编译为 JavaScript
TypeScript 主题 包含一个示例,该示例创建一个任务,用于将 TypeScript 编译为 JavaScript,并从 VS Code 中观察任何相关错误。
将 Less 和 SCSS 编译为 CSS
CSS 主题提供了如何使用任务生成 CSS 文件的示例。
定义问题匹配器
VS Code 内置了一些最常见的问题匹配器。但是,有许多编译器和 linting 工具,它们都产生自己的错误和警告样式,因此您可能希望创建自己的问题匹配器。
我们有一个 helloWorld.c 程序,开发人员错误地将 printf 拼写为 prinft。使用 gcc 编译它将产生以下警告
helloWorld.c:5:3: warning: implicit declaration of function ‘prinft’
我们希望生成一个问题匹配器,它可以捕获输出中的消息并在 VS Code 中显示相应的问题。问题匹配器严重依赖于 正则表达式。以下部分假设您熟悉正则表达式。
提示: 我们发现 RegEx101 playground,它具有 ECMAScript (JavaScript) 风格,是开发和测试正则表达式的好方法。
捕获上述警告(和错误)的匹配器如下所示
{
// The problem is owned by the cpp language service.
"owner": "cpp",
// The file name for reported problems is relative to the opened folder.
"fileLocation": ["relative", "${workspaceFolder}"],
// The name that will be shown as the source of the problem.
"source": "gcc",
// The actual pattern to match problems in the output.
"pattern": {
// The regular expression. Example to match: helloWorld.c:5:3: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
// The first match group matches the file name which is relative.
"file": 1,
// The second match group matches the line on which the problem occurred.
"line": 2,
// The third match group matches the column at which the problem occurred.
"column": 3,
// The fourth match group matches the problem's severity. Can be ignored. Then all problems are captured as errors.
"severity": 4,
// The fifth match group matches the message.
"message": 5
}
}
请注意,文件、行和消息属性是强制性的。fileLocation 指定任务输出中生成并在问题中匹配的文件路径是 absolute 还是 relative。如果任务生成绝对路径和相对路径,您可以使用 autoDetect 文件位置。使用 autoDetect,路径首先作为绝对路径进行测试,如果文件不存在,则假定路径是相对路径。
severity 指定如果模式不包含严重性,则使用哪种问题严重性。severity 的可能值为 error、warning 或 info。
这是一个完成的 tasks.json 文件,其中包含上面代码(已删除注释)并包装了实际的任务详细信息
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "gcc",
"args": ["-Wall", "helloWorld.c", "-o", "helloWorld"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceFolder}"],
"source": "gcc",
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
}
]
}
在 VS Code 中运行它并按下 ⇧⌘M (Windows, Linux Ctrl+Shift+M) 获取问题列表,您将获得以下输出

注意: C/C++ 扩展 包含 GCC 的问题匹配器,因此无需自定义。
模式中还可以使用其他几个属性。这些是
- location - 如果问题位置是 line 或 line,column 或 startLine,startColumn,endLine,endColumn,那么可以使用我们的通用位置匹配组。
- endLine - 问题结束行的匹配组索引。如果编译器未提供结束行值,则可以省略。
- endColumn - 问题结束列的匹配组索引。如果编译器未提供结束列值,则可以省略。
- code - 问题代码的匹配组索引。如果编译器未提供代码值,则可以省略。
您还可以定义一个只捕获文件的“问题匹配器”。为此,请定义一个 pattern,其中可选的 kind 属性设置为 file。在这种情况下,无需提供 line 或 location 属性。
注意: 如果
kind属性设置为file,则功能模式必须至少提供file和message的匹配组。如果未提供kind属性或kind属性设置为location,则功能模式还必须提供line或location属性。
注意: 问题匹配器仅解析给定命令的输出。如果您想解析写入单独文件(例如日志文件)的输出,请让您运行的命令在执行完成之前打印出单独文件中的行。
定义多行问题匹配器
有些工具会将源文件中发现的问题分散到多行上,尤其是在使用 stylish 报告器时。一个例子是 ESLint;在 stylish 模式下,它会产生如下输出
test.js
1:0 error Missing "use strict" statement strict
✖ 1 problems (1 errors, 0 warnings)
我们的问题匹配器是基于行的,因此我们需要使用与实际问题位置和消息(1:0 error Missing "use strict" statement)不同的正则表达式来捕获文件名(test.js)。
要做到这一点,请为 pattern 属性使用问题模式数组。这样,您就可以为您要匹配的每一行定义一个模式。
以下问题模式匹配 ESLint 在 stylish 模式下的输出 - 但仍然有一个我们需要接下来解决的小问题。下面的代码有一个第一个正则表达式来捕获文件名,第二个正则表达式来捕获行、列、严重性、消息和错误代码
{
"owner": "javascript",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": [
{
"regexp": "^([^\\s].*)$",
"file": 1
},
{
"regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning|info)\\s+(.*)\\s\\s+(.*)$",
"line": 1,
"column": 2,
"severity": 3,
"message": 4,
"code": 5
}
]
}
然而,如果一个资源上出现多个问题,此模式将不起作用。例如,想象一下 ESLint 的以下输出
test.js
1:0 error Missing "use strict" statement strict
1:9 error foo is defined but never used no-unused-vars
2:5 error x is defined but never used no-unused-vars
2:11 error Missing semicolon semi
3:1 error "bar" is not defined no-undef
4:1 error Newline required at end of file but not found eol-last
✖ 6 problems (6 errors, 0 warnings)
模式的第一个正则表达式将匹配“test.js”,第二个将匹配“1:0 error ...”。下一行“1:9 error ...”被处理,但未被第一个正则表达式匹配,因此未捕获任何问题。
为了使其工作,多行模式的最后一个正则表达式可以指定 loop 属性。如果设置为 true,它会指示任务系统将多行匹配器的最后一个模式应用于输出中的行,只要正则表达式匹配。
第一个模式捕获的信息(在本例中匹配 test.js)将与后续每一行匹配 loop 模式的行结合起来,以创建多个问题。在此示例中,将创建六个问题。
这是一个问题匹配器,可以完全捕获 ESLint stylish 问题
{
"owner": "javascript",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": [
{
"regexp": "^([^\\s].*)$",
"file": 1
},
{
"regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning|info)\\s+(.*)\\s\\s+(.*)$",
"line": 1,
"column": 2,
"severity": 3,
"message": 4,
"code": 5,
"loop": true
}
]
}
注意:如果同一资源上出现多个具有完全相同行和列的问题,则只会显示一个问题。这适用于所有问题匹配器,而不仅仅是多行问题匹配器。
修改现有问题匹配器
如果现有问题匹配器与您的需求接近,您可以在 tasks.json 任务中修改它。例如,$tsc-watch 问题匹配器仅适用于已关闭的文档。如果您希望它适用于所有文档,则可以修改它
{
"type": "npm",
"script": "watch",
"problemMatcher": {
"base": "$tsc-watch",
"applyTo": "allDocuments"
},
"isBackground": true
}
其他可修改的问题匹配器属性包括 background、fileLocation、owner、pattern、severity 和 source。
后台/监视任务
有些工具支持在后台运行,同时监视文件系统中的更改,并在磁盘上的文件更改时触发操作。在 Gulp 中,此类功能通过 npm 模块 gulp-watch 提供。TypeScript 编译器 tsc 通过 --watch 命令行选项内置了对此功能的支持。
为了提供后台任务在 VS Code 中处于活动状态并产生问题结果的反馈,问题匹配器必须使用额外的信息来检测输出中的这些 state 更改。让我们以 tsc 编译器为例。当编译器以监视模式启动时,它会向控制台打印以下额外信息
> tsc --watch
12:30:36 PM - Compilation complete. Watching for file changes.
当磁盘上包含问题的文件更改时,会出现以下输出
12:32:35 PM - File change detected. Starting incremental compilation...
src/messages.ts(276,9): error TS2304: Cannot find name 'candidate'.
12:32:35 PM - Compilation complete. Watching for file changes.
查看输出显示以下模式
- 当控制台打印
File change detected. Starting incremental compilation...时,编译器运行。 - 当控制台打印
Compilation complete. Watching for file changes.时,编译器停止。 - 在这两个字符串之间报告问题。
- 编译器在初始启动时也会运行一次(不向控制台打印
File change detected. Starting incremental compilation...)。
为了捕获此信息,问题匹配器可以提供一个 background 属性。
对于 tsc 编译器,适当的 background 属性如下所示
"background": {
"activeOnStart": true,
"beginsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
"endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
}
除了问题匹配器上的 background 属性外,任务本身也必须标记为 isBackground,以便任务在后台持续运行。
一个在监视模式下运行的 tsc 任务的完整手写 tasks.json 如下所示
{
"version": "2.0.0",
"tasks": [
{
"label": "watch",
"command": "tsc",
"args": ["--watch"],
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"fileLocation": "relative",
"pattern": {
"regexp": "^([^\\s].*)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$",
"file": 1,
"location": 2,
"severity": 3,
"code": 4,
"message": 5
},
"background": {
"activeOnStart": true,
"beginsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
"endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
}
}
}
]
}
后续步骤
这就是任务 - 让我们继续...
- tasks.json 架构 - 您可以查看完整的
tasks.json架构和描述。 - 基本编辑 - 了解功能强大的 VS Code 编辑器。
- 代码导航 - 快速浏览您的源代码。
- 语言支持 - 了解我们支持的编程语言,包括 VS Code 自带的和通过社区扩展提供的。
- 调试 - 直接在 VS Code 编辑器中调试您的源代码。
常见问题
任务可以使用与集成终端中指定的不同的 shell 吗?
是的。您可以使用 "terminal.integrated.automationProfile.*" 设置来设置所有 VS Code 自动化(包括任务)将使用的 shell。
"terminal.integrated.automationProfile.windows": {
"path": "cmd.exe"
}
或者,您可以使用 options.shell 属性覆盖任务的 shell。您可以按任务、全局或按平台设置。例如,要在 Windows 上使用 cmd.exe,您的 tasks.json 将包含
{
"version": "2.0.0",
"windows": {
"options": {
"shell": {
"executable": "cmd.exe",
"args": [
"/d", "/c"
]
}
}
},
...
后台任务可以在 launch.json 中用作 prelaunchTask 吗?
是的。由于后台任务会一直运行直到被终止,因此后台任务本身没有信号表示它已经“完成”。要将后台任务用作 prelaunchTask,您必须为后台任务添加适当的后台 problemMatcher,以便任务系统和调试系统能够知道任务“完成”了。
您的任务可以是
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true
}
注意:
$tsc-watch是一个 后台 问题匹配器,这是后台任务所必需的。
然后您可以在 launch.json 文件中将任务用作 prelaunchTask
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/out/src/**/*.js"],
"preLaunchTask": "npm: watch"
}
有关后台任务的更多信息,请参阅 后台/监视任务。
运行任务时为什么会出现“command not found”?
当您尝试运行的任务命令未被您的终端识别为可运行的命令时,就会出现“command not found”消息。最常见的情况是,命令作为您的 shell 启动脚本的一部分进行配置。任务以非登录和非交互方式运行,这意味着您的 shell 的启动脚本不会运行。特别是 nvm 已知会使用启动脚本作为其配置的一部分。
有几种方法可以解决此问题
- 确保您的命令在您的路径中,并且不需要启动脚本才能添加到您的路径。这是解决此问题最彻底的方法,也是推荐的解决方案。
- 您可以为您的任务进行一次性修复,使其作为登录或交互式运行。不建议这样做,因为它可能会产生其他后果。但是,对于单个任务来说,它也可以是一个快速简便的修复。下面是一个使用
bash作为 shell 执行此操作的任务示例
{
"type": "npm",
"script": "watch",
"options": {
"shell": {
"args": ["-c", "-l"]
}
}
}
上面的 npm 任务将运行 bash 并带有一个命令(-c),就像任务系统默认所做的那样。但是,此任务还会将 bash 作为登录 shell (-l) 运行。