CLOVER🍀

That was when it all began.

Visual Studio Codeで、Node.jsアプリケーションをデバッグする(ローカルプロセスアタッチ/リモートデバッグ)

これは、なにをしたくて書いたもの?

  • Visual Studio Codeを使って、Node.jsのアプリケーションのデバッグを試してみたい
  • ローカルプロセスへのアタッチや、リモートデバッグができるようなので、そちらを中心に

というわけで、Visual Studio Codeでのこれらのデバッグ機能を試してみます。

ドキュメントでの記載

Node.jsのドキュメントにもVisual Studio Codeでの記載がありますし

Visual Studio Code 1.10+ In the Debug panel, click the settings icon to open .vscode/launch.json. Select "Node.js" for initial setup.

Debugging - Getting Started | Node.js

Visual Studio Codeのドキュメントにもデバッガーとしての内容が書かれています。

Build Node.js Apps with Visual Studio Code

Debug Node.js Apps using Visual Studio Code

.vscode/launch.jsonファイルでの「request」の指定で、エディタから起動するプロセスをデバッグするか、外部のプロセスに
アタッチするかを指定できるようです。

Supported Node-like runtimes

今回は、外部のプロセスにアタッチする方を扱います。

環境

今回確認した環境は、こちらです。

$ node -v
v10.13.0


$ npm -v
6.4.1

Visual Studio Codeのバージョンは、1.28.2です。

サンプルプログラム

まずは、デバッグを行うためのサンプルプログラムを作りましょう。

Expressを使った、小さいアプリケーションを作ることにします。Expressをインストール。

$ npm i -S express

バージョンは、こちら。

  "dependencies": {
    "express": "^4.16.4"
  }

作成したアプリケーション。 server.js

const express = require("express");
const app = express();

app.get('/message', (req, res) => {
    const message = 'Hello Node.js!!';

    res.send(message);
});

app.listen(8080);

package.jsonのscript部分は、まずはこう。

  "scripts": {
    "start": "node server.js"
  },

通常のデバッグ

あまり触れませんが、通常のデバッグを少しだけ。

メニューから「Debug」→「Open Configurations」を選び、.vscode/launch.jsonファイルを作成します。

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "プログラムの起動",
            "program": "${workspaceFolder}/index.js"
        }
    ]
}

雛形はこんな感じなので、「program」の部分のパスを作成したスクリプトのファイル名に変更すれば
「Debug」→「Start Debugging」でデバッグ実行が可能です。

            "program": "${workspaceFolder}/server.js"

こんな感じで。
f:id:Kazuhira:20181108233453p:plain

ブレークポイントを仕掛けたところ。
f:id:Kazuhira:20181108233538p:plain

とまあ、これで簡単な確認とlaunch.jsonファイルが作成できました。

ローカルプロセスにアタッチする

では、今度はローカルプロセスにアタッチしてみましょう。

launch.jsonをこのように変更します。

    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "プログラムの起動",
            "processId": "${command:PickProcess}"
        }
    ]

「request」を「attach」に、それから「processId」を追加して「${command:PickProcess}」とします。

これで、Visual Studio Code外からプログラムを起動してみます。

$ npm start

> vscode-debugging@1.0.0 start /path/to/vscode-debugging
> node server.js

この状態で、メニューから「Debug」→「Start Debugging」を選択すると、Node.jsのプロセスが表示されるので、
適切なプロセスを選択します。
f:id:Kazuhira:20181108234518p:plain

選択すると、プロセスにアタッチされ、アタッチされたプロセス側にはこんな出力が行われます。

Debugger listening on ws://127.0.0.1:9229/ba7391d3-ab47-4080-9297-c2e4a8bcaae2
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.

あとは、エディタ上からプロセスを起動した時と同じようにデバッグが可能です。

リモートデバッグする

最後は、リモートデバッグ。

launch.jsonをこのように変更します。

    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "プログラムの起動",
            "address": "localhost",
            "port": 9229
        }
    ]

「address」と「port」を追加しました。

そして、package.jsonでのnodeコマンドの起動引数に、「--inspect」を追加します。

  "scripts": {
    "start": "node --inspect server.js"
  },

この状態でプログラムを起動すると、このように表示されるので

$ npm start

> vscode-debugging@1.0.0 start /path/to/vscode-debugging
> node --inspect server.js

Debugger listening on ws://127.0.0.1:9229/c31afa22-bf4c-43bd-91a3-99f792bcd3d5
For help, see: https://nodejs.org/en/docs/inspector

他と同じようにメニューから「Debug」→「Start Debugging」を選択すると、プロセスにアタッチされデバッグが可能に
なります。

Debugger attached.

また、「--inspect」にリッスンするアドレス、ポートを指定することで

  "scripts": {
    "start": "node --inspect=192.168.0.2:9229 server.js"
  },

launch.jsonで指定する「address」、「port」を使ってリモートに接続できるのですが、Node.jsのドキュメントでは
SSHのポートフォワードでトンネリングすることが紹介されており、こちらの方法を勧めていそうな感じですね。

$ ssh -L 9221:localhost:9229 user@remote.example.com

Debugging - Getting Started | Node.js

まあ、なんにせよ、Visual Studio Codeを使ったローカルプロセスへのアタッチや、リモートデバッグの方法がわかったので
良しとしましょう。