MENU

VisualStudioCode

【VSCode】外部コマンドをタスク登録して作業効率をアップ

更新日:2022/09/12

タスクとは

 

プログラミングをしていると、コマンドプロンプトやターミナルなど外部コマンドを実行することがあります。
例えば、ソースにコンパイル等を行い実行可能な形式にしたり、テンプレート的なものを適用するなどです。

 

VSCodeはメニューの表示から「ターミナル」を選択すると、ターミナルを画面内で開けます。
ここで外部コマンドを実行できます。

 

ターミナル

 

起動するターミナルは、変更可能です。次の記事はWindowsについて書いたものですが、他のOSでの参考になると思います。
【VSCode】ターミナルでコマンドプロンプトを使う

 

しかし、毎回コマンドを入力するのは面倒です。
そこで起動するコマンドを登録しておき、簡単な操作で実行できると作業効率が上がりますね。

 

その仕組みがタスクです。

 

さらにタスクは、ターミナルを介すことなくプログラムを実行することもできます。
ターミナル特有の機能や実行結果等の確認が必要ないとき、バックグランドでプロセスを実行させるときなどは、こちらを利用します。

 

タスクには、ワークスペース(プロジェクト)内で使用できるカスタムタスクと、VSCode全体で利用できるユーザー タスクの2種類があります。

tasks.jsonの生成

 

タスクは tasks.json で定義します。
初期状態では、このファイルが存在しません。

 

カスタムタスクおよびユーザータスクの tasks.json は、次の方法で作成します。

 

 

カスタムタスクのtasks.json生成

 

カスタムタスクは、ワークスペース(プロジェクト)単位のタスクです。

 

このタスク用のtasks.jsonを生成するには、まず、メニューのターミナルから「タスクの構成...」を選択します。

 

タスクの構成

 

上の画面の「npm:」の2行は、VSCodeがNode.jsの package.json がフォルダ内に生成されていることを検知して自動で表示したものです。
ESLintなどのモジュールが含まれていると、表示されるコマンドが増えます。
これらを選択すると、そのコマンドを反映した tasks.json が生成されます。

 

同様に「Grunt」「Gulp」「Jake」も自動で表示されます。
上の図では検出が無効になっているので、有効にするときはクリックして設定してください。

 

これら以外のタスクを生成するときは、「テンプレートから tasks.json を生成」を選択します。

 

テンプレートから tasks.json を生成

 

上の図は4つのコマンドが表示されています。
目的のタスクが上から3つのものと一致するなら、その項目を選択します。
異なるなら「Others」を選択します。

 

今回は、「Others」を選択します。
すると、次の内容で tasks.json が生成されます。

 

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello"
        }
    ]
}

 

ユーザー タスクのtasks.json生成

 

ユーザータスクは、VSCode全体で使用できるタスクです。

 

ユーザー タスクのtasks.jsonは、次の手順で生成します。

 

  1. メニューの表示から「コマンドパレット...」を選択する。

     

  2. タスク:ユーザータスクを開く」を選択する。

     

    タスク:ユーザータスクを開く

     

  3. 目的とするタスクを選択する。

     

    タスクの構成

     

  4.  

    最後の画面は、カスタムタスクと同じですね。
    「Others」を選択すると、カスタムタスクと同じ内容で VSCodeのデータフォルダに tasks.jsonが生成されます。

タスクの実行

 

タスクは次の二つの方法で実行できます。

 

 

メニューから実行

 

タスクをメニューから実行するときは、メニューのターミナルから「タスクの実行...」を選択します。

 

表示された画面から目的のタスクを選択して実行します。

 

タスクを選択して実行

 

タスク名の横に「ユーザー」と表示されているタスクは、ユーザータスクです。
今回は、カスタムタスクも登録したのに、表示されていません。

 

こんなときは一番下にある「すべてのタスクの表示...」を選択します。

 

すべてのタスクの表示

 

これで、全てのタスクが実行できます。

 

キーボードショートカットから実行

 

キー入力でコマンドを実行するキーボードショートカット機能に、タスクを登録することも可能です。

 

keybinding.json を開いて次のコードを入力します。

 

    {
        "key": "ctrl+shift+alt+p",
        "command": "workbench.action.tasks.runTask",
        "args":"echo",
    }

 

このコードは、"key"に対応するキーがキーボードで入力されたとき、workbench.action.tasks.runTask コマンドを実行します。

 

"arg"は workbench.action.tasks.runTask コマンドの引数です。
tasks.json の "label"に記述した値を指定します。

 

カスタムタスクユーザータスクに同じ"label"がある場合は、カスタムタスクが優先されます。

 

今後ユーザータスクを指定して実行できるようになるかもしれません。
(今もあって僕が方法を知らないだけかもしれません)
しかしユーザータスクをショートカットに割り付けるときは、重複しないようにした方がいいと思います。

 

キーボードショートカットについては、次の記事を読んでみてください。
【VSCode】キーボードショートカットを編集してみる

tasks.jsonのフォーマット

 

次は、tasks.jsonのフォーマットについて解説します。

 

最低限必要なプロパティ

 

タスクとして成立させるのに最低限必要なプロパティは、次の3つです。

 

プロパティ名意味備考
"label"タスクの名前同じファイル内で重複可能
"type"タスクのタイプ

"shell"または"process"

"shell":ターミナルを開いて"command"を実行
"process": "command" を実行
"command"実行するコマンド

 

tasks.json:最低限の構成例

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "こんにちは",
            "type": "shell",
            "command": "echo こんにちは"
        }
    ]
}

 

"label"について

 

"label"は日本語を使用できます。支障が無ければ日本語で具体的に記述しておいたほうが分かりやすいと思います。
また、同じファイル内で"label"の値を重複できますが、実行できるのは最後の一つのみです。

 

"type"について

 

"type""shell"を指定した場合はターミナル上で実行されるので、"command"に環境変数PATHが適用されます。
ターミナルごとに実行できるコマンドや引数、文法などが異なるので、起動するターミナルの種類を把握しておく必要がありますね。

 

"type""process"を指定した場合はPATHが適用されません。
そのため"command"はフルパスで指定する必要があります。
また、引数は "arg"で指定します。

 

Windowsなどで \ を使用するときは、"c:\\users\\abcde" のように \を二つ重ねる必要があります。
また " "内で " を使用するときは、" \"abc def\" "のように 前方に\ を付加します。

 

 

 

引数指定

 

"type""shell"のとき、"command"に引数を含めることができますが、"args"を使用すると個別に指定できます。

 

また前項でも触れていますが、"type""process"指定した場合は、引数を "args"で指定する必要があります。

 

"args"プロパティ

 

"args"プロパティは、基本的には文字列の配列で指定します。

 

前項の例を、"args"を使用するように変更してみます。

 

tasks.json:"args"の使用例

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "こんにちは",
            "type": "shell",
            "command": "echo"
            "args": ["こんにちは"]
        }
    ]
}

 

タスクを実行すると、前項の結果と同じになります。

 

コーテーションの適用

 

コマンドライン上でスペースがあると、区切りとして判定されます。
スペースも含めて一つの値として渡したいとき、困りますね。

 

その対応策として、シングルコーテーションかダブルコーテーションで文字を囲います。

 

VSCodeのタスク機能はこの点を考慮してあるようで、"args"にスペースが入っていると、ターミナルの特性に合わせてシングルコーテーションかダブルコーテーションのどちらかを文字列の前後に付加してくれます。

 

この動作は、"args"の文字列をオブジェクトに置き換えることで変更できます。

 

次のコードは、Node.js で test.js を実行しています。
その際、スペースが含まれたフォルダ名を引数ととして渡しています。

 

  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
      "command": "node",
      "args": [
        "test.js",
        { 
          "value":"c:\\document folder\\abcde",
          "quoting": "strong",
        }
      ]
    }
  ]

 

"value"で、引数として渡す文字列を指定します。

 

"quoting"で、コーテーションの有無を制御します。
"quoting"は、次の値が使用できます。

 

意味備考
"escape"エスケープコーテーションを付加せずにエスケープを行う
"strong"強い引用変数等の特殊文字をそのまま出力するようにコーテーションを付加
"weak"弱い引用変数等の特殊文字が展開されるようにコーテーションを付加

 

実際に値通りの動作をするかどうかは、ターミナル側の動作に依存します。

 

例えば Windowsのコマンドプロンプトは"strong""weak"の両方でダブルコーテーションが付加されます。また"strong"を指定しても、変数(%PATH%など)は展開されます。

 

ターミナル・外部プログラムの起動オプション

 

"options"プロパティを使用すると、ターミナルや外部プログラム起動時のカレントディレクトリや環境変数を定義できます。

 

"options"で使用できるプロパティは3つです。

 

意味備考
"cwd"カレントディレクトリ

(フォルダ)

省略時は現在のワークスペースディレクトリ
"env"環境変数現在の環境変数を上書き
"shell"実行するターミナルを定義

"type""shell"時有効)


二つのプロパティで定義
"executable":実行するプログラムをフルパスで指定
"args":プログラムに渡す引数を文字列配列で指定

 

"options"の例

  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
      "options": {
        "env": {
          "PATH": "c:\\mydir;${env:path}"
        },
        "shell": {
          "executable": "${env:windir}\\system32\\cmd.exe",
          "args": ["/C"]
        }
      },
      "command": "echo こんにちは",
    }
  ]

 

実際には現在のターミナル上で、次のコマンドが実行されます。

 

${env:windir}\\system32\\cmd.exe /C echo こんにちは

 

cmd.exe(コマンドプロンプト)は /C オプションがあると、その後のコマンドを実行して終了します。
このオプションがないときは cmd.exeが起動するだけで、目的の echo を実行してくれません。
僕は気が付かなくて、2時間くらい悩みました…

 

他のターミナルでも同じようなオプションがないか、確認する必要がありますね。

 

問題マッチャ―

 

タスクには、ソースファイルを読み込んで処理するプログラム、例えばコンパイラやESLintなどからの出力を解析して、ソースファイルの問題点を問題パネルに表示する機能があります。

 

解析は問題についての出力かどうかを正規表現でマッチングして判断します。

 

マッチングの定義は"problemMatcher"プロパティでおこないます。

 

問題マッチャ―については次の記事で解説しているので、参考にしてみてください。
【VSCode】タスクの問題マッチャ―(problemMatcher)を理解してみる

複合タスク

 

VSCodeのタスク機能は、"dependsOn""dependsOrder"プロパティで複数のタスクを一つのタスクにまとめることができます。

 

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
      "command": "echo こんにちは",
    },
    {
      "label": "こんばんは",
      "type": "shell",
      "command": "echo こんばんは",
    },
    {
      "label": "こんにちは&こんばんは",
      "dependsOn":["こんにちは","こんばんは"],
      "dependsOrder": "sequence"
    }
  ]
}

 

"dependsOn"と"dependsOrder"

 

各プロパティは、次のような意味があります。

 

プロパティ名意味備考
"dependsOn"実行するタスクタスクのラベルを配列形式で記述
"dependsOrder"実行タイミング文字列で指定

"parallel" : 並列で実行されます(規定値)
"sequence" : 順番に実行されます

 

"type""shell""dependsOrder""parallel"のとき、複数のターミナルが起動します。
"sequence"なら、同じターミナルで順番に実行されます。

 

依存関係

 

上のコードでは、複合タスクでコマンドを実行していませんが、複合タスク内で"type""command"を指定して、コマンドを実行できます。

 

このとき複合タスクは、"dependsOn"のタスクに依存しています。
つまり、"dependsOrder"のタスクを実行したあとに、複合タスクのコマンドが実行されます。

 

ビルド・テストタスク

 

タスクには特別なタスクとして、ビルドタスクとテストタスクがあります。

 

特別と言っても「ビルドタスクの実行」と「テストタスクの実行」というコマンドが適用されるだけですが…

 

これらのタスクの定義は他と同じように tasks.json で行い、"group"プロパティを使用します。

 

次のコードは、ビルドタスクとテストタスクを定義しています。

 

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
      "command": "echo こんにちは",
      "group": "test"
    },
    {
      "label": "こんばんは",
      "type": "shell",
      "command": "echo こんばんは",
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

 

"group"プロパティは、文字列かオブジェクトで指定します。

 

文字列のときは、次の3つを指定できます。

 

"build" : ビルドタスク
"test" :テストタスク
"none" :通常のタスク

 

オブジェクトは、"kind""isDefault"の二つをプロパティとして持ちます。

 

"kind"は、文字列の時と同じ値"build""test""none"のどれかです。

 

"isDefault"は、同じグループ名のタスクが複数あるときに規定タスクとして使用するかどうかを定義します。

 

規定タスクがある、またはグループのタスクが一つの場合、「ビルドタスクの実行」または「テストタスクの実行」を実行すると、規定タスクが起動します。
規定タスクが無く、グループのタスクが複数ある場合は、タスクを選択する画面が表示されます。

ターミナルパネルの制御

 

"presentation"プロパティを使用すると、タスクを実行しているターミナル画面の動作を制御できます。

 

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
      "command": "echo こんにちは",
      "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": false,
        "panel": "shared",
        "showReuseMessage": true,
        "clear": false,
        "close": false,
        "group": "hello",
        "revealProblems": "always"
      }
    }
  ]
}

 

"presentation"のプロパティは、次のようになっています。

 

プロパティ名意味備考
"echo"実行したコマンドをターミナルに出力するかどうかtrue:する(規定値)

false:しない

"reveal"ターミナルパネルを表示するかどうか文字列で指定

"always":する(規定値)
"never": しない
"silent": 問題が検知された時のみ表示

"focus"ターミナルパネルをフォーカスするかどうかtrue:する

false:しない(規定値)

"panel"ターミナルパネルを共有するかどうか文字列で指定

"shared":する(規定値)
"dedicated":しない。同じタスクは共有する
"new":しない。毎回新規でターミナル起動

"showReuseMessage"「ターミナルはタスクによって再利用されます。

閉じるには任意のキーを押してください」
を表示するかどうか

true:する(規定値)
false:しない
"clear"タスク実行前にターミナルをクリアするかどうかtrue:する

false:しない(規定値)

"close"タスク終了後にターミナルを閉じるかどうかtrue:閉じる

false:閉じない(規定値)

"group"タスクのグループ名。

同じ名前のタスクはターミナルを共有する

文字列で指定
名前は何でもいい
"revealProblems"問題パネルを表示するかどうかどうか文字列で指定

"always":する
"never": しない(規定値)
"onProblem": 問題が検知された時のみ表示

 

"revealProblems"は、"reveal"よりも優先されます。

 

ここでの"表示する"は、表示されていないときに表示するかどうかです。
表示されているものを非表示することは、ありません。

その他のプロパティ

 

tasks.json で使用できるプロパティは、まだまだあります。
いくつかピックアップしてみます。

 

OS別の定義

 

起動するターミナルやコマンドなどの仕様はOS毎に異なることが多いです。
異なるOSで開発やテストを行う場合、環境が変わるたびに tasks.json を書き換えるのは面倒です。

 

そのため、OS毎にコマンド等を指定できる機能があります。
次のように"windows""osx""linux"プロパティで記述します。

 

OS毎のコマンド指定例

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
     
      "windows":{
        "options": {
          "env": {
            "PATH": "c:\\mydir;${env:path}"
          },
          "shell": {
            "executable": "${env:windir}\\system32\\cmd.exe",
            "args": ["/C"]
          }
        },
        "command": "echo こんにちは",
      },
      "osx":{

      },
      "linux":{
        
      }
    }
  ]
}

 

各プロパティ内は、次の4つのプロパティが使用できます。

 

 

タスクの実行画面の定義

 

タスクの実行画面で表示される内容を、3つのプロパティで定義できます。

 

タスクの実行画面で表示される内容

 

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "こんにちは",
      "type": "shell",
      "detail": "\"こんにちは\"と表示します",
      "hide": false,
      "icon": {
        "color": "terminal.ansiBlue",
        "id": "compass"
      },

      "command": "echo こんにちは",

    }
  ]

 

プロパティ名内容備考
"hide"タスクの実行画面に表示するかどうかtrue:表示しない

false:表示する(規定値)

"detail"タスクの説明文字列で指定
"icon"タスクのアイコンオブジェクトで指定
{
  "color" : アイコンの色,
  "id" : アイコンのID
}

 

"icon""color""id"は、エディター上で表示される候補から選択します。

 

複合タスクの"dependsOn"で指定していて直接実行しないタスクは、"hide"で非表示にしておくといいですね。

 

タスク実行に関する定義

 

プロパティ名内容備考
"instanceLimit"同時に実行できるタスク(インスタンス)の数数値で指定
"reevaluateOnRerun"最後のタスクを再実行コマンドで実行するときの変数の評価方法を制御true:変数を再評価

false:前回の結果を維持

"runOn"タスクの実行タイミング文字列で指定

"default": タスクの実行で実行
"folderOpen": ワークスペースが開かれた時実行

 

"runOn"の値が"folderOpen"のとき、タスクを実行するかどうか確認されます。
task.allowAutomaticTasks設定を"on"にすると、確認されないようにできます。

 

 

タスク実行中の終了動作

 

"promptOnClose"プロパティは、タスク実行中にVSCodeを閉じたとき、確認メッセージを表示するかどうかを定義します。

 

trueのとき、確認します。

 

 

スポンサーリンク

記事の内容について

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

OFUSEを設置してみました。
応援いただけると嬉しいです。