在VSCode中定义多个任务

83
我看到可以在 VSCode 中定义任务。但是我不确定如何在 `tasks.json` 文件中定义多个任务。

一流的支持已经在VS Code 1.9(2017年1月)中添加,消除了在此处看到的顶部答案中所见到的解决方法的需要。请参见我的答案。 (https://dev59.com/L10a5IYBdhLWcg3wsKe2#43566702)。 - vossad01
答案可以在这里找到:https://dev59.com/zVcP5IYBdhLWcg3w5d_Q#50241977 - pasx
13个回答

36

如果有需要帮助的人…如果你没有/不想要使用gulp/grunt等或者另外一个shell脚本来代理你的任务命令,“npm run”已经可以胜任。

这适用于webpack和mocha,“构建和测试”,Shift+Ctrl+BShift+Ctrl+T

.vscode/tasks.json:

{
  "name": "npmTask",
  //...
  "suppressTaskName": true,
  "command": "npm",
  "isShellCommand": true,
  "args": [
    "run"
  ],
  "tasks": [
    {
      //Build Task
      "taskName": "webpack",
      //Run On Shift+Ctrl+B
      "isBuildCommand": true,
      //Don't run when Shift+Ctrl+T
      "isTestCommand": false,
      // Show the output window if error any
      "showOutput": "silent",
      //Npm Task Name
      "args": [
        "webpack"
      ],
      // use 2 regex:
      // 1st the file, then the problem       
      "problemMatcher": {
        "owner": "webpack",
        "severity": "error",
        "fileLocation": "relative",
        "pattern": [
          {
            "regexp": "ERROR in (.*)",
            "file": 1
          },
          {
            "regexp": "\\((\\d+),(\\d+)\\):(.*)",
            "line": 1,
            "column": 2,
            "message": 3
          }
        ]
      }
    },
    {
      //Test Task   
      "taskName": "mocha",
      // Don't run on Shift+Ctrl+B
      "isBuildCommand": false,
      // Run on Shift+Ctrl+T
      "isTestCommand": true,
      "showOutput": "always",
      "args": [
        "mocha"
      ]
    }
  ]
}

package.json:

{
  ...
  "scripts": {
    "webpack": "webpack",
    "mocha": "/usr/bin/mocha"
  },
  ...
}

不错的解决方案!因此,您在npm脚本标签中定义了实际命令,然后从tasks.json调用npm脚本。我真的很想直接在tasks.json中定义任务。这似乎有点多余? - Kokodoko

13

帮助我更好地理解这一点的是传递给命令的参数序列。对于一些人来说可能很明显,但在文档中并不清楚。

为了聚焦于被发送的命令,省略了一些字段:

{ "command": "myCommand"
  "args": ["myCommandArguments"],
  "tasks" : [ 
    { "taskName": "myTask",
      "args": ["myTaskArguments"],
      "suppressTaskName": false,
    }
  ]
}

上述定义将导致以下命令:

myCommand myCommandArguments myTaskArguments myTask

任务名称 myTask 总是最后一个。自版本0.4以来,可以使用 "suppressTaskName": true 来省略它。


哇,我简直不敢相信这个答案,但我尝试了一下,它是真的有效。我想在VSCode中创建一个任务,用于执行“gulp --no-color vet --verbose”,但为了让它正常工作,我必须将参数用作任务,并将任务用作参数,例如在tasks.json中使用“gulp --no-color --verbose vet”,其中vet是我的任务,--verbose是一个参数。当然,这会导致具有相同参数的任务出现问题,因此该任务以其参数命名,并在VSCode任务运行选项中列出。 - GJSmith3rd
但是如果我想要不同的任务使用不同的命令怎么办?例如,一个任务应该运行node-sass,另一个任务应该运行tsc? - Kokodoko

13

试试这个

{
    "version": "0.1.0",
    "command": "cmd",
    "isShellCommand": true,
    "args": ["/C"],
    "tasks": [
        {
            "taskName": "install",
            "args": ["npm install"]
        },
        {
            "taskName": "build",
            "args": ["gulp build"],
            "isBuildCommand": true,
            "problemMatcher": "$gulp-tsc"
        }
    ]
}

更多信息呢?出了什么错误?我正在使用VS Code 0.8.0,它运行良好。 - AlexStack
在切换输出时,我看到了标准的cmd.exe onrun输出。就像这样:Microsoft Windows [Version 10.0.10240] (c) Корпорация Майкрософт (Microsoft Corporation),2015 г. Все права защищены。//俄语版权所有 - neftedollar
@neftedollar 这只适用于Windows。如果您正在寻找适用于Mac的东西,请将“command”:“cmd”更改为“command”:“sh”,并将“args”:[“/ c”]更改为“args”:[“-c”]。 - ra9r
@raiglstorfer 谢谢,它在我的Windows电脑上无法工作。 - neftedollar

10
我使用以下的tasks.json文件来运行多个TypeScript构建场景。我在每个文件夹中都放置了一个tsconfig.json文件,这样可以让我分别调整每个文件夹的输出。只需确保抑制任务名称,因为它会尝试将其放入命令字符串中。
{
    "version": "0.1.0",
    "command": "tsc",
    "showOutput": "always",
    "isShellCommand": true,
    "args": [],
    "windows": {
        "command": "tsc",
        "showOutput": "always",
        "isShellCommand": true
    },
    "tasks": [
        {
            "taskName": "Build the examples",
            "suppressTaskName": true,
            "isBuildCommand": false,            
            "args": ["-p", "./source/examples", "--outDir", "./script/examples"],
            "problemMatcher": "$tsc"
        },
        {
            "taskName": "Build the solution",            
            "suppressTaskName": true,
            "isBuildCommand": false,        
            "args": ["-p", "./source/solution", "--outDir", "./script/solution"],
            "problemMatcher": "$tsc"
        }   
    ]
}
这是文件夹结构的样子,其中 /script 是输出根目录,/source 是输入根目录。两个文件夹都参考了 /typingd 文件夹和 /typings 文件夹中的类型声明。TypeScript 在使用外部引用时受到相对路径的限制,因此如果这些文件夹结构类似,则有助于简化操作。

TypeScript 多构建文件夹结构

哦,是的,如果你将它们标记为“非构建”,并覆盖构建键以从列表中选择特定任务,就更容易有选择地启动它们。

// Place your key bindings in this file to overwrite the defaults
[
    { "key": "ctrl+shift+b", "command": "workbench.action.tasks.runTask" }
]

更新:如果您想要的话,您总是可以完全采取不受限制的行动。处理参数可能有更好的方法,但目前在OSX下这对我有效。

{
  "version": "0.1.0",
  "isShellCommand": true,
  "linux": { "command": "sh", "args": ["-c"] },
  "osx": { "command": "sh", "args": ["-c"] },
  "windows": { "command": "powershell", "args": ["-Command"] },
  "tasks": [
    {
      "taskName": "build-models",
      "args": ["gulp build-models"],
      "suppressTaskName": true,
      "isBuildCommand": false,
      "isTestCommand": false
    },
    {
      "taskName": "run tests",
      "args": ["mocha ${workspaceRoot}/test"],
      "suppressTaskName": true,
      "isBuildCommand": false,
      "isTestCommand": false
    }
  ]
}

2
这是一个非常清晰的例子!这可能是微软打算使用tasks.json的方式(遗憾的是他们没有自己解释这一点)。唯一的问题是:如果我有不同的命令行任务怎么办?(我需要一个tsc任务和一个node-sass任务) - Kokodoko
3
请参见更新内容,了解运行多个独立命令的方法。 - djabraham
我同意,当你想要使用tsc和node-sass时,单一的“构建命令”会带来麻烦。不得不安装和学习第三方构建工具(比如gulp)很让人沮丧。而且,为不同的操作系统列出不同的命令处理器也很让人沮丧。 - Jon Watte

7

我不知道这个问题的正式答案(也想知道),但在此提供我丑陋的解决方法,希望能对大家有所帮助。 由于我使用的是Windows系统,我创建了一个简单的批处理脚本,内容如下:

"%1" "%2"

然后,我的tasks.json看起来像这样:
{
    "version": "0.1.0",
    "command": "c:\\...\\mytasks.bat"
    "tasks" : [
        {
            "taskName": "myFirstTask",
            "args": "c:\\...\\task1.exe", "${file}"],
        },
        {
            "taskName": "mySecondTask",
            "args": "c:\\...\\task2.exe", "${file}"],
        },
    ]
}

我终于搞定了。大约在过去的9个月中,VS Code开始将taskName添加到任务的arg 1上。因此,我的批处理文件变成了:“%2”“%3”,而不是你所拥有的。如果这保持一致,我可能会回来编辑这个解决方案。 - phil

6

您可以在tasks属性中列出多个任务。例如:

"tasks": [
    {
        "taskName": "build",
        ...
    },
    {
         "taskName": "package",
         ...
    }
]

7
他们必须使用相同的命令,但只能改变参数,不能有其他变化。 - Edward B.
是的,Edward B.,由于某种原因,目前所有的博客文章都假定你刚开始使用VS Code,并且还没有任务 :S。但是你必须在根节点上设置“suppressTaskName”: true,然后可以在子任务中设置“taskName”,以便使用不同的命令。请参见@Dan的tscmocha任务示例。 - Bart

4
这项功能是在Visual Studio Code v1.9 (2017年1月)中添加的。示例和文本来自发布说明
{
  "version": "0.1.0",
  "tasks": [
    {
      "taskName": "tsc",
      "command": "tsc",
      "args": ["-w"],
      "isShellCommand": true,
      "isBackground": true,
      "problemMatcher": "$tsc-watch"
    },
    {
      "taskName": "build",
      "command": "gulp",
      "args": ["build"],
      "isShellCommand": true
    }
  ]
}

每个任务的命令

现在您可以定义每个任务不同的命令(#981)。这使得在不编写自己的shell脚本的情况下,可以为不同的任务运行不同的命令。使用每个任务的命令的tasks.json文件如上所示。


3

这似乎是VSCode v0.5.0版本中的一个Bug

所以我添加了这个答案来展示之前由@hurelu解释过的工作示例。我的tasks.json文件:

{
    "version": "0.1.0",
    "command": "gulp",
    "isShellCommand": true,
    "args": [
        "--no-color"
    ],
    "tasks": [
        {
            "taskName": "--verbose",
            "isBuildCommand": true,
            "showOutput": "always",
            "args": [
                "vet"
            ],
            "problemMatcher": [
                "$jshint",
                "$jshint-stylish"
            ]
        },
        {
            "taskName": "vet",
            "isTestCommand": true,
            "showOutput": "always",
            "args": [],
            "problemMatcher": [
                "$jshint",
                "$jshint-stylish"
            ]
        }
    ]
}

我的 gulp.js:

/// <reference path="typings/tsd.d.ts" />

var gulp = require('gulp');
var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs');
var util = require('gulp-util');
var gulpprint = require('gulp-print');
var gulpif = require('gulp-if');
var args = require('yargs').argv;

gulp.task('vet', function () {
    log('Analyzing source with JSHint and JSCS');

    return gulp
        .src
        ([
            './src/**/*.js',
            './*.js'
        ])
        .pipe(gulpif(args.verbose, gulpprint()))
        .pipe(jscs())
        .pipe(jshint())
        .pipe(jshint.reporter('jshint-stylish', { verbose: true }))
        .pipe(jshint.reporter('fail'));
});

gulp.task('hello-world', function () {
    console.log('This is our first Gulp task!');
});

////////////
function log(msg) {
    if (typeof (msg) === 'object') {
        for (var item in msg) {
            if (msg.hasOwnProperty(item)) {
                util.log(util.colors.blue(msg[item]));
            }
        }
    } else {
        util.log(util.colors.blue(msg));
    }

}

注意第一个任务使用了isBuildCommand,因此按下CTRL+SHFT+B会启动该任务,而下一个任务是isTestCommand,因此按下CTRL+SHFT+T会启动该任务。但是,为了使第一个任务接受args,任务名称和args必须颠倒顺序。

自VSCode 0.5.0以来,以上内容可行,但以下内容不可行:

{
    "version": "0.1.0",
    "command": "gulp",
    "isShellCommand": true,
    "args": [
        "--no-color"
    ],
    "tasks": [
        {
            "taskName": "vet",
            "isBuildCommand": true,
            "showOutput": "always",
            "args": [
                "--verbose"
            ],
            "problemMatcher": [
                "$jshint",
                "$jshint-stylish"
            ]
        },
        {
            "taskName": "vet",
            "isTestCommand": true,
            "showOutput": "always",
            "args": [],
            "problemMatcher": [
                "$jshint",
                "$jshint-stylish"
            ]
        }
    ]
}

以下是正确任务和参数顺序的task.json输出:
[10:59:29] Using gulpfile ~/Workspaces/Examples/Gulp/pluralsight-gulp/gulpfile.js
[10:59:29] Task 'default' is not in your gulpfile
[10:59:29] Please check the documentation for proper gulpfile formatting

当使用args时,以下是tasks.json中任务名称和参数颠倒的正确输出:

[11:02:44] Using gulpfile ~/Workspaces/Examples/Gulp/pluralsight-gulp/gulpfile.js
[11:02:44] Starting 'vet'...
[11:02:44] Analyzing source with JSHint and JSCS
[gulp] src/server/app.js
[gulp] src/client/app/app.module.js
[gulp] src/client/test-helpers/bind-polyfill.js
[gulp] src/client/test-helpers/mock-data.js
[gulp] src/server/routes/index.js
[gulp] src/client/app/core/config.js
[gulp] src/client/app/core/constants.js
[gulp] src/client/app/core/core.module.js
[gulp] src/client/app/core/dataservice.js
[gulp] src/client/app/core/dataservice.spec.js
[gulp] src/client/app/customers/customer-detail.controller.js
[gulp] src/client/app/customers/customer-detail.controller.spec.js
[gulp] src/client/app/customers/customers.controller.js
[gulp] src/client/app/customers/customers.controller.spec.js
[gulp] src/client/app/customers/customers.module.js
[gulp] src/client/app/customers/customers.route.js
[gulp] src/client/app/customers/customers.route.spec.js
[gulp] src/client/app/dashboard/dashboard.controller.js
[gulp] src/client/app/dashboard/dashboard.controller.spec.js
[gulp] src/client/app/dashboard/dashboard.module.js
[gulp] src/client/app/dashboard/dashboard.route.js
[gulp] src/client/app/dashboard/dashboard.route.spec.js
[gulp] src/client/app/layout/ht-sidebar.directive.js
[gulp] src/client/app/layout/ht-sidebar.directive.spec.js
[gulp] src/client/app/layout/ht-top-nav.directive.js
[gulp] src/client/app/layout/layout.module.js
[gulp] src/client/app/layout/shell.controller.js
[gulp] src/client/app/layout/shell.controller.spec.js
[gulp] src/client/app/layout/sidebar.controller.js
[gulp] src/client/app/layout/sidebar.controller.spec.js
[gulp] src/client/app/widgets/ht-img-person.directive.js
[gulp] src/client/app/widgets/ht-widget-header.directive.js
[gulp] src/client/app/widgets/widgets.module.js
[gulp] src/client/tests/server-integration/dataservice.spec.js
[gulp] src/server/routes/utils/errorHandler.js
[gulp] src/server/routes/utils/jsonfileservice.js
[gulp] src/client/app/blocks/exception/exception-handler.provider.js
[gulp] src/client/app/blocks/exception/exception-handler.provider.spec.js
[gulp] src/client/app/blocks/exception/exception.js
[gulp] src/client/app/blocks/exception/exception.module.js
[gulp] src/client/app/blocks/logger/logger.js
[gulp] src/client/app/blocks/logger/logger.module.js
[gulp] src/client/app/blocks/router/router-helper.provider.js
[gulp] src/client/app/blocks/router/router.module.js
[gulp] gulpfile.js
[gulp] karma.conf.js
[11:02:48] Finished 'vet' after 4.37 s

2
截至2017年2月发布,您可以使用Terminal Runner并设置依赖任务来组合多个任务。 它有点奇怪,因为它会为每个任务打开一个单独的终端窗口,您必须观察以查看是否工作,并记住关闭(它们"堆叠"在一起),而且您不会收到"完成"通知,但它能够完成工作。 此功能是初步的,但很有前途。 以下是运行Cordova应用程序的tsc和jspm的示例。
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [{
        "taskName": "tsc",
        "command": "tsc",
        "isShellCommand": true,
        "args": ["-p", "."],
        "showOutput": "always",
        "problemMatcher": "$tsc"
    }, {
        "taskName": "jspm",
        "command": "jspm",
        "isShellCommand": true,
        "args": ["bundle-sfx", "www/app/main.js", "www/dist/bundle.js", "--inline-source-maps", "--source-map-contents"],
        "showOutput": "always"
    },
    {
        "taskName": "build",
        "isBuildCommand": true,
        "dependsOn": ["tsc", "jspm"]
    }]
}

1
以下对我有用:

tasks.json:

{
    "version": "0.1.0",
    "command": "cmd",
    "isShellCommand": true,
    "args": [
        "/c"
    ],
    "tasks": [
        {
            "taskName": "bower",
            "args" : ["gulp bower"],
            "isBuildCommand": true,
            "showOutput": "always"
        },
        {
            "taskName": "unittest",
            "suppressTaskName": true,
            "args" : ["dnx -p ${cwd}\\test\\MyProject.UnitTests test"],
            "isTestCommand": true,
            "showOutput": "always"
        }
    ]
}

MyProject.UnitTests\project.json:

 "commands": {
    "test": "xunit.runner.dnx"
  }

运行 Bower:从 VSCode 中按 Ctrl + Shift + B
运行测试:从 VSCode 中按 Ctrl + Shift + T


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接