第2回 Visual Studio Codeのデバッグ構成ファイルの基本:Node.js編特集:Visual Studio Codeデバッグ入門

Visual Studio Codeはlaunch.jsonファイルで構成を行うことで、デバッグをさまざまに構成可能だ。Node.jsを対象に構成ファイルの取り扱いの基本を説明する。

» 2017年08月04日 05時00分 公開
[かわさきしんじInsider.NET編集部]
「特集:Visual Studio Codeデバッグ入門」のインデックス

連載目次

 前回は、Visual Studio Code(以下、VS Code)でデバッグを行うために基本事項を取り上げた。その中で最後に説明したlaunch.jsonファイル(デバッグの構成ファイル)について見てみよう。

launch.jsonファイルの概要

 前回も述べた通り、launch.jsonファイルは[デバッグ]ビューにある['launch.json' を構成または編集してください]ボタン(歯車のボタン)をクリックすることで、作成できる。このときに、VS Codeがどの環境でのデバッグ構成を行おうとしているのかを自動的に判断してくれるが、うまく判断できなかった場合には、問い合わせを行うメッセージが表示されるので、そこでデバッグ環境を指定してやる。以下はExpressベースのアプリをexpress-generatorを使用して作成し、launch.jsonファイルを作成しようとしたところだ。

構成用のボタン(赤枠内)をクリック。すると、以下のような問い合わせが行われることもある
構成用のボタン(赤枠内)をクリック。すると、以下のような問い合わせが行われることもある
その場合は、環境を選んで指定してやる
その場合は、環境を選んで指定してやる

構成ファイルの作成


 ここではNode.js+Expressな環境でデバッグを行うので、[Node.js]を選択した。すると、次のようなlaunch.jsonファイルが作成される。ファイルが作成されるのは、VS Codeで開いている最上位のディレクトリにある.vscodeディレクトリだ。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceRoot}\\bin\\www"
    }
  ]
}


作成されたlaunch.jsonファイル

 なお、launch.jsonファイルの生成時には、VS Codeがpackage.jsonファイルの内容などを見て、自動的に構成を行ってくれる部分もある(上のprogram属性など)。では、このファイルの内容について見ていこう。

launch.jsonファイルに記述する属性

 launch.jsonファイルは、さまざまな環境に応じて、さまざまな構成で作成されるが、それら全てで必須となる属性としては以下のものがある。

属性 説明
type デバッガーの種別
request デバッグ時にプログラムを起動するか(launch)、既に起動しているプログラムにデバッガーをアタッチするか(attach)
name デバッグ構成として表示する名前
必須の属性

 上に示したlaunch.jsonファイルを見ると、type属性の値はもちろん"node"となっている。request属性の値は新規にプログラムを起動することを意味する"launch"に、name属性の値は"Launch Program"となっていて、これがデバッグに使用する構成の名前としてVS Codeに表示される。

launch.jsonファイル作成後、[デバッグ]ビューに[Launch Program]と表示されているところ launch.jsonファイル作成後、[デバッグ]ビューに[Launch Program]と表示されているところ
(1)に示すように、name属性に指定した値が[デバッグの開始]ボタンに現在のデバッグ構成として表示される。

 最後のprogram属性はデバッグ実行時に起動するプログラムのパスを指定するもので、多くのデバッグ環境がサポートしている。前述した通り、ここではExpressベースのプロジェクトをexpress-generatorを使用して作成したので、そのエントリポイントとなる「bin\www」ファイルが指定されている。

 request属性には"launch"か"attach"を指定可能であり、前者を指定すればデバッグ開始時にプログラムが新規に起動され、後者を指定すれば既に起動中のプログラムにアタッチする。アタッチ用の構成を加えると、launch.jsonファイルは次のようになる。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceRoot}\\bin\\www"
    },
    {
      "type": "node",
      "request": "attach",
      "name": "Attach Program"
    }
  ]
}


アタッチ用の構成を追加したlaunch.jsonファイル

 アタッチ用の構成では、起動するプログラムのパスは不要なので記述しない(記述できない)。このような構成にすると、[デバッグの開始]ボタンの右にあるドロップダウンに2つの構成が表示されるようになる。このような設定にすれば、コンソールや統合ターミナルなどからプログラムをデバッグモードで起動している状態で、[Attach Program]を選択してデバッグを実行すれば、起動中のプログラムにアタッチできる。これについては後で実際に見てみよう。

2つの構成が表示されるようになった 2つの構成が表示されるようになった

 Node.js用のlaunch.jsonファイルには、この他にも多くの属性を記述可能だ。そのうちの幾つかを抜粋して以下に示す。まずはrequest属性が"launch"でも"attach"でも使用できるものから。

属性 説明
protocol デバッグに使用するプロトコル
port/address デバッグで使用するポート/IPアドレス
stopOnEntry プログラム起動直後にデバッグ実行を中断するか
sourceMaps ソースマップを有効にするかどうか
outFiles トランスパイル後のJavaScriptファイルの位置を指定。ソースマップ有効時に指定する
smartStep ソースマップの対象外のコードのステップ実行を省略するかどうか
skipFiles ステップ実行の対象外とするファイルを指定
trace 診断出力の設定
request属性が"launch"でも"attach"でも記述可能な属性

 request属性が"launch"の場合には、以下の属性もサポートされる。

属性 説明
program 起動するプログラムのパス
args デバッグ実行時にプログラムに渡す引数
cwd デバッグ実行を行うディレクトリ
runtimeExecutable 使用するランタイム環境
runtimeArgs ランタイム環境に渡す引数
env 環境変数の指定
envFile 環境関数を定義したファイル
console プログラムを起動するコンソールの種類を指定
request属性が"launch"の場合にサポートされる属性

 request属性が"attach"の場合には以下がサポートされる。

属性 説明
processId アタッチするプロセスのプロセスID
request属性が"attach"の場合にサポートされる属性

 この他にも、デバッグを開始する前に実行するタスクを指定するpreLaunchTask属性、デバッグコンソールの表示を制御するinternalConsoleOptions属性などを利用可能だ。次にExpressベースのプログラムを実際にデバッグ実行しながら、幾つかの属性を見てみよう。

Expressアプリのデバッグ

 本稿ではexpress-generatorを使用して、Expressアプリを作成して、ほんの少しだけ手を加えている。Express自体の詳しい説明はしないので、興味のある方は公式サイトや「Node.jsのMVCフレームワーク「Express」の基礎知識とインストール」などを参照されたい。

本稿で扱うExpressアプリ 本稿で扱うExpressアプリ

 見ての通り、スケルトンコードで表示されるウエルカムメッセージの下にテキストボックスとボタンを配置しただけのもので、すぐに想像できるように、テキストボックスに何かを入力して[hello]ボタンをクリックすると、その下に「Hello XXX」のようなメッセージが表示されるようになっている。

 生成されたコードのうち、手を加えたのはindex.jsファイルとindex.jadeファイルだ。index.jsファイルでは入力を受け取ったら、それを加工して、index.pugファイルで定義されているビューを表示している。

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/', function(req, res) {
  let name = req.body.name;
  console.log(name);
  res.render('index', { title: 'Express', msg: `Hello ${name}` });
});

module.exports = router;

変更したindex.jsファイル

 index.pugファイルでは、上で見たUI要素を定義している。

extends layout

block content
  h1= title
  p Welcome to #{title}
  form(action='/', method='POST')
    input(type='text', name='name', size=40)
    input(type='submit', value='hello')
    p #{msg}


変更したindex.pugファイル

 launch.jsonファイルでは上でも見た通り、プログラムの起動とアタッチの両方の設定を行ってある。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceRoot}\\bin\\www"
    },
    {
      "type": "node",
      "request": "attach",
      "name": "Attach Program"
    }
  ]
}


launch.jsonファイル

 以下では、launch.jsonファイルの構成を変えながら、デバッグ実行を行っていくことにする。

[Launch Program]構成でデバッグ

 まずは上に示した基本構成で、デバッグ時にプログラムを新規に起動するパターンを見てみよう。これには単に[デバッグ]ビューで[Launch Program]を選択して、[デバッグの開始]ボタンをクリックするだけだ。ここでは10行目にブレークポイントを設定した。

[Launch Program]構成でデバッグ [Launch Program]構成でデバッグ

 デバッグ実行を開始すると、デバッグツールバー(ウィンドウ上部)やパネル(ウィンドウ右下)が表示され、パネルでは[デバッグ コンソール]タブが選択される(パネルが表示されない場合はメニューバーから[表示]−[デバッグ コンソール]を選択するか、[Ctrl]+[Shift]+[Y]キーを押す)。

デバッグ実行が始まったところ デバッグ実行が始まったところ

 ここでテキストボックスに何かを入力して、[hello]ボタンを押すと、実行が中断される。これはいつものデバッグの様子だ。ここでデバッグ実行の開始時に、一度、実行を中断して、いろいろと確認したいとする。その場合には、stopOnEntry属性だ。デバッグ実行を中断して、これを追加してみよう。

{
  "version": "0.2.0",
  "configurations": [
    {
      …… 省略 ……
      "stopOnEntry": true
    },
    {
      …… 省略 ……
    }
  ]
}


stopOnEntry属性をtrueに設定

 この構成でデバッグ実行を開始すると、Expressアプリのエントリポイントである「bin\www」ファイルの先頭で実行が中断されるようになる。

bin\wwwファイルの先頭で実行が中断したところ bin\wwwファイルの先頭で実行が中断したところ
VS Codeのエディタ画面にエントリポイントであるbin\wwwファイルが表示されている点に注意。

 このように、launch.jsonファイルに構成を追加していくことで、細やかな構成でデバッグを行えるようになる。もう1つの例として、Node.jsのコアモジュールのステップ実行をスキップする構成を以下に示す。

{
  "version": "0.2.0",
  "configurations": [
    {
      …… 省略 ……
      "skipFiles": [
        "<node_internals>/**/*.js"
      ]
    },
    {
      …… 省略 ……
    }
  ]
}


Node.jsのコアモジュールのステップイン実行をスキップする構成

 skipFiles属性にはglob形式でステップインを飛ばしたいファイル群を指定していく。上で使っている「<node_internals>」はNode.jsの組み込みコアモジュールを参照する「マジックネーム」となっている。よって、この記述を追加すれば、Node.jsの内部モジュールの実行がスキップされるようになる(またno_modulesディレクトリ以下の全ての.jsファイルをスキップするには「"${workspaceRoot}/node_modules/**/*.js」を追加すればよいようにも思えるが、筆者が試したところでは期待した通りにはスキップされなかった。筆者の期待が間違っている可能性がある)。

 ステップ実行がスキップされたファイルについては、[デバッグ]ビューの[コール スタック]ペーンで薄いグレーで表示されるようになる。ファイルをスキップするルールなどについては「Skipping uninteresting code」ページを参照されたい。

ステップ実行がスキップされたファイルは薄いグレーで表示される(赤枠内に注目) ステップ実行がスキップされたファイルは薄いグレーで表示される(赤枠内に注目)

 次にアタッチをしてみよう。

[Attach Program]構成でデバッグ

 まずはコンソールや統合ターミナルから「node debug bin\www」「node --debug bin\www」などのコマンドを入力して、デバッグモードでアプリを実行する。あるいはpackage.jsonファイルにデバッグ用のスクリプトを記述して、「npm run-script debug」などとしてもよい。

 例えば、以下は統合ターミナルからコマンドラインでプログラムをデバッグモードで実行しているところだ。

--debug-brkオプションを指定してプログラムを実行したところ --debug-brkオプションを指定してプログラムを実行したところ

 そして、[デバッグ]ビューで[Attach Program]構成を選択して、[デバッグの開始]ボタンを実行する。アタッチができれば後は通常通りにデバッグを行える。

アタッチしてデバッグを行っているところ アタッチしてデバッグを行っているところ

 デバッグ用のツールバーの右端には、アタッチを解除するボタンがあるので、デバッグが終了したらこれをクリックしよう(ただし、起動したプログラムは依然として実行を続けた状態となるので注意)。

npmスクリプト経由でプログラムをデバッグ実行する

 VS Codeではnpmをランタイム環境としてデバッグを行うことも可能だ。これには、runtimeExecutable属性を指定する。例えば、package.jsonファイルに以下のようなデバッグ用スクリプトを追加し、その設定を利用してデバッガーを起動できる。ここではInspectorプロトコルを使うように指定している(デフォルトのポート番号は9229)。

{
  "name": "expressapp",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "debug": "node --inspect ./bin/www"
  },
  "dependencies": {
    …… 省略 ……
  }
}


Inspectorプロトコルを使用して、デバッグ実行を行う

 このとき、対応するlaunch.jsonファイルのエントリは次のようになる。

{
  "version": "0.2.0",
  "configurations": [
    {
      …… 省略 ……
    },
    {
      …… 省略 ……
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Launch from npm script",
      "runtimeExecutable": "C:\\Program Files\\nodejs\\npm.cmd",
      "runtimeArgs": [
        "run-script", "debug"
      ],
      "protocol": "inspector",
      "port": 9229
    }
  ]
}


対応するlaunch.jsonファイルのエントリ
runtimeExecutable属性とruntimeArgs属性、protocol属性、port属性を指定している

 ここではruntimeExecutable属性にはnpmへのフルパスを指定している(筆者が試したところでは単に「npm」とするだけではうまくいかなかったため)。runtimeArgs属性にはnpmに与える引数を指定する。「npm run-script debug」コマンドを実行するので、ここでは"run-script"と"debug"を指定している。protocol属性にはpackage.jsonで指定した「"node --inspect ./bin/www"」に合わせて"inspector"を指定し、port属性にはInspectorプロトコルで使用するデフォルトポート番号の9229を指定している。

 この状態で、[Launch from npm script]を選択して[デバッグの開始]ボタンをクリックすれば、[デバッグ コンソール]パネルからプログラムが起動されて、デバッグ実行が開始される。

 この辺りの設定は結構面倒くさいところがあり(特にVS Codeの側でいろいろと気を使ってくれるのが、逆に分かりにくくなっているような気がする)、試行錯誤が必要になるかもしれない。うまくいかないときには、ポートとプロトコルを適切に設定できているかに注意しよう。


 今回はNode.jsプログラムのデバッグを行う際に、そのデバッグ構成を行う方法を見た。本稿では取り上げなかった属性もたくさんあるので、興味のある方は「Node.js Debugging in VS Code」ページや「Node.js Tutorial in VS Code」ページなどを参照されたい。

 次回はVS Codeで.NET Coreコードをデバッグするための構成などについて見ていく予定だ。

「特集:Visual Studio Codeデバッグ入門」のインデックス

特集:Visual Studio Codeデバッグ入門

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。