【VSCode】tasks.jsonでビルドやLintを自動化する方法

Editor

VSCodeではtasks.jsonを使うことで、ビルドやLint、テスト、ウォッチなどの繰り返し作業をエディタ内から統一的に自動化できます。拡張機能に依存せずコマンドを記述でき、ワークスペースやフォルダごとに共有可能なため、チーム開発でも環境差を抑えられます。ここではtasks.jsonの基本構造から、npmやESLint、TypeScriptなどの実用例、問題マッチャーや複合タスク、入力変数の活用、デバッグ連携までを一気に解説します。

tasks.jsonの基本構造

設定ファイルはプロジェクト直下の.vscode/launch.jsonと並び、.vscode/tasks.jsonとして保存します。必ずversionとconfigurationsを定義し、typeやcommand、problemMatcherなどをタスクごとに記述します。

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build:ts",
      "type": "shell",
      "command": "tsc -p tsconfig.json",
      "problemMatcher": "$tsc",
      "group": "build"
    }
  ]
}

シェルタスクとnpmタスクの書き分け

シェルに直接コマンドを書く場合はtypeをshellにします。npmスクリプトを呼び出す場合はtypeをnpmにし、scriptにpackage.json内のスクリプト名を指定します。環境依存を減らすならnpm run経由が安全です。

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "lint",
      "type": "npm",
      "script": "lint",
      "problemMatcher": "$eslint-stylish"
    },
    {
      "label": "test",
      "type": "npm",
      "script": "test"
    }
  ]
}

問題マッチャーでエラーをエディタに反映する

problemMatcherを設定すると、ターミナル出力からファイル名や行番号を解析してエディタに赤線や一覧を表示できます。代表的なプリセットとしてTypeScriptは$tsc、ESLintは$eslint-stylishが利用できます。独自のツールでも正規表現を用意すれば対応可能です。

{
  "label": "sass:build",
  "type": "shell",
  "command": "sass src/scss:dist/css --no-source-map",
  "problemMatcher": {
    "owner": "scss",
    "fileLocation": ["relative", "${workspaceFolder}"],
    "pattern": {
      "regexp": "^(.*):(\\d+):(\\d+):\\s*(error|warning):\\s*(.*)$",
      "file": 1,
      "line": 2,
      "column": 3,
      "severity": 4,
      "message": 5
    }
  }
}

監視タスクとバックグラウンド実行

ウォッチモードではタスクをバックグラウンド扱いにすることで、VSCodeがビルド完了や再ビルドのタイミングを把握できます。isBackgroundをtrueにし、初回成功を通知するパターンを指定します。

{
  "label": "webpack:watch",
  "type": "shell",
  "command": "webpack --watch",
  "isBackground": true,
  "problemMatcher": {
    "owner": "webpack",
    "fileLocation": "absolute",
    "pattern": [
      {
        "regexp": "^(ERROR in)\\s+(.*)$",
        "message": 2,
        "severity": 1
      }
    ],
    "background": {
      "activeOnStart": true,
      "beginsPattern": "Compiled",
      "endsPattern": "Compiled successfully"
    }
  }
}

入力変数とカスタムプロンプトの活用

タスク実行時にユーザーへ入力を求めてコマンドへ渡せます。inputsにpromptStringやpickStringを定義し、${input:キー}で参照します。ワークフローの分岐を対話的に選べるため、スクリプトを増やさず柔軟に運用できます。

{
  "version": "2.0.0",
  "inputs": [
    {
      "id": "env",
      "type": "pickString",
      "description": "実行環境を選択",
      "options": ["dev", "staging", "prod"],
      "default": "dev"
    }
  ],
  "tasks": [
    {
      "label": "deploy",
      "type": "shell",
      "command": "npm run deploy -- --env ${input:env}"
    }
  ]
}

複数ステップをまとめる複合タスク

ビルド、Lint、テストを連続実行したい場合はdependsOnで束ねます。並列化が必要ならdependsOrderをparallelにします。前処理と後処理を確実に通したいときに有効です。

{
  "version": "2.0.0",
  "tasks": [
    { "label": "lint", "type": "npm", "script": "lint" },
    { "label": "build", "type": "npm", "script": "build" },
    { "label": "test", "type": "npm", "script": "test" },
    {
      "label": "ci:all",
      "dependsOn": ["lint", "build", "test"],
      "dependsOrder": "sequence"
    }
  ]
}

デバッグとの連携でワンキー起動を実現する

launch.jsonのpreLaunchTaskにタスクラベルを指定すると、デバッグ開始前に自動でビルドが走ります。ウォッチタスクをbackgroundとしておけば、デバッグ中に差分ビルドも継続します。

// .vscode/tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "tsc:build",
      "type": "shell",
      "command": "tsc -p tsconfig.json",
      "problemMatcher": "$tsc",
      "group": "build"
    }
  ]
}
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Node App",
      "program": "${workspaceFolder}/dist/index.js",
      "preLaunchTask": "tsc:build"
    }
  ]
}

クロスプラットフォーム対応と環境変数の扱い

WindowsとUnix系でコマンドが異なる場合はoptionsのshellArgsやcommandをOSごとに切り替える記述が便利です。process指定の環境変数を使いたい場合はoptions.envで上書きできます。

{
  "label": "open:dist",
  "type": "shell",
  "windows": { "command": "start http://localhost:5173" },
  "osx":     { "command": "open http://localhost:5173" },
  "linux":   { "command": "xdg-open http://localhost:5173" }
}

ESLintとTypeScriptの定番タスク例

実務でよく使う組み合わせとして、ESLintの自動修正とTypeScriptの型チェックを分けて定義しておくと、編集段階のクイック修正とCI用の厳密チェックを切り替えられます。

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "eslint:fix",
      "type": "shell",
      "command": "npx eslint \"src/**/*.{ts,tsx,js,jsx}\" --fix",
      "problemMatcher": "$eslint-stylish"
    },
    {
      "label": "tsc:check",
      "type": "shell",
      "command": "npx tsc -p tsconfig.json --noEmit",
      "problemMatcher": "$tsc"
    }
  ]
}

つまずきポイントとデバッグの勘所

labelの重複で呼び出しに失敗することがあります。ラベルは一意にして呼び出し側と一致させます。problemMatcherが効かない場合は正規表現のfileLocationやパターンの桁数を見直します。タスクが終了せず待ち続ける場合はisBackgroundやbackgroundのbeginsPatternとendsPatternが誤っている可能性があります。ターミナルで単体実行して期待する標準出力が得られているかを確認し、出力文言に合わせてパターンを調整すると安定します。

まとめ

tasks.jsonはビルドやLint、テスト、デプロイまでをエディタ内に集約し、コマンド実行とエラー可視化を自動化するための中核です。シェルタスクとnpmタスクを使い分け、problemMatcherでエラーをエディタに反映し、dependsOnで複数工程を束ね、inputsで柔軟に分岐させれば、日々の反復作業がワンアクションで完結します。デバッグ連携やバックグラウンド監視も組み合わせ、プロジェクトに最適な開発体験を設計していきましょう。