に参加して、VS Code の AI 支援開発について学びましょう。

VS Code で Node.js のデバッグ

Visual Studio Code エディターには、Node.js ランタイムのデバッグ機能が組み込まれており、JavaScript、TypeScript、および JavaScript にトランスパイルされる他の多くの言語をデバッグできます。Node.js のデバッグ用にプロジェクトを設定するのは簡単で、VS Code は適切な起動構成のデフォルトとスニペットを提供します。

VS Code で Node.js プログラムをデバッグするには、いくつかの方法があります。

自動アタッチ

自動アタッチ機能が有効になっている場合、Node デバッガーは、VS Code の統合ターミナルから起動された特定の Node.js プロセスに自動的にアタッチします。この機能を有効にするには、コマンド パレット (⇧⌘P (Windows、Linux Ctrl+Shift+P)) から自動アタッチの切り替えコマンドを使用するか、すでに有効になっている場合は自動アタッチステータス バー項目を使用します。

自動アタッチには 3 つのモードがあり、結果として表示されるクイック ピックとdebug.javascript.autoAttachFilter設定を介して選択できます。

  • smart - node_modules フォルダーの外部でスクリプトを実行したり、mocha や ts-node のような一般的な「ランナー」スクリプトを使用したりすると、プロセスがデバッグされます。「ランナー」スクリプトの許可リストは、自動アタッチ スマート パターン設定 (debug.javascript.autoAttachSmartPattern) を使用して構成できます。
  • always - 統合ターミナルで起動されたすべての Node.js プロセスがデバッグされます。
  • onlyWithFlag - --inspect または --inspect-brk フラグで起動されたプロセスのみがデバッグされます。

自動アタッチを有効にした後、ターミナルの右上にある ⚠ アイコンをクリックするか、新しいターミナルを作成してターミナルを再起動する必要があります。その後、デバッガーは 1 秒以内にプログラムにアタッチされるはずです。

Auto Attach

自動アタッチがオンの場合、VS Code ウィンドウの下部にあるステータス バーに「自動アタッチ」項目が表示されます。これをクリックすると、自動アタッチ モードを変更したり、一時的にオフにしたりできます。自動アタッチを一時的にオフにすると、デバッグが不要な単発のプログラムを実行しているが、機能を完全に無効にしたくない場合に便利です。

追加構成

その他の起動構成プロパティ

debug.javascript.terminalOptions 設定で、通常 launch.json に見られる他のプロパティを自動アタッチに適用できます。たとえば、node 内部を skipFiles に追加するには、ユーザー設定またはワークスペース設定に次の行を追加できます。

  "debug.javascript.terminalOptions": {
    "skipFiles": [
      "<node_internals>/**"
    ]
  },

自動アタッチ スマート パターン

smart 自動アタッチ モードでは、VS Code はコードにアタッチしようとし、デバッグに関心のないビルド ツールにはアタッチしません。これは、メイン スクリプトを グロブ パターンのリストと照合することで行われます。グロブ パターンは、debug.javascript.autoAttachSmartPattern 設定で構成でき、デフォルトは次のとおりです。

[
  '!**/node_modules/**', // exclude scripts in node_modules folders
  '**/$KNOWN_TOOLS$/**' // but include some common tools
];

$KNOWN_TOOLS$ は、ts-nodemochaava などの一般的な「コード ランナー」のリストに置き換えられます。これらの設定が機能しない場合、このリストを変更できます。たとえば、mocha を除外して my-cool-test-runner を含めるには、2 行を追加できます。

[
  '!**/node_modules/**',
  '**/$KNOWN_TOOLS$/**',
  '!**/node_modules/mocha/**', // use "!" to exclude all scripts in "mocha" node modules
  '**/node_modules/my-cool-test-runner/**' // include scripts in the custom test runner
];

JavaScript デバッグターミナル

自動アタッチと同様に、JavaScript デバッグターミナルは、そこで実行する Node.js プロセスを自動的にデバッグします。コマンド パレット (kbs(workbench.action.showCommands)) からデバッグ: JavaScript デバッグターミナルを作成コマンドを実行するか、ターミナル切り替えドロップダウンからJavaScript デバッグターミナルを作成を選択することで、デバッグターミナルを作成できます。

Create Debug Terminal

追加構成

その他の起動構成プロパティ

debug.javascript.terminalOptions 設定で、通常 launch.json に見られる他のプロパティをデバッグターミナルに適用できます。たとえば、node 内部を skipFiles に追加するには、ユーザー設定またはワークスペース設定に次の行を追加できます。

"debug.javascript.terminalOptions": {
  "skipFiles": [
    "<node_internals>/**"
  ]
},

起動構成

起動構成は、VS Code でデバッグを設定する従来の​​方法であり、複雑なアプリケーションを実行するための最も多くの構成オプションを提供します。

このセクションでは、より高度なデバッグシナリオ向けの構成と機能について詳しく説明します。ソースマップを使用したデバッグ、外部コードのステップオーバーリモートデバッグなど、多くのデバッグ方法に関する説明があります。

入門ビデオをご覧になりたい場合は、VS Code でのデバッグの開始をご覧ください。

: VS Code を始めたばかりの場合は、デバッグトピックで、一般的なデバッグ機能と launch.json 構成ファイルの作成について学ぶことができます。

起動構成属性

デバッグ構成は、ワークスペースの .vscode フォルダーにある launch.json ファイルに保存されます。デバッグ構成ファイルの作成と使用に関する概要は、一般的なデバッグ記事に記載されています。

以下は、Node.js デバッガーに固有の一般的な launch.json 属性の参照です。オプションの完全なセットは、vscode-js-debug options ドキュメントで確認できます。

次の属性は、launch および attach タイプ起動構成でサポートされています。

  • outFiles - 生成された JavaScript ファイルを見つけるためのグロブ パターンの配列。ソースマップセクションを参照してください。
  • resolveSourceMapLocations - ソースマップを解析する必要がある場所のグロブ パターンの配列。ソースマップセクションを参照してください。
  • timeout - セッションを再起動するときに、このミリ秒数を超えたら中止します。Node.js へのアタッチセクションを参照してください。
  • stopOnEntry - プログラムの起動時にすぐにブレークします。
  • localRoot - VS Code のルート ディレクトリ。リモート デバッグセクションを参照してください。
  • remoteRoot - Node のルート ディレクトリ。リモート デバッグセクションを参照してください。
  • smartStep - ソース ファイルにマップされないコードを自動的にステップオーバーしようとします。スマート ステップセクションを参照してください。
  • skipFiles - これらのグロブ パターンでカバーされるファイルを自動的にスキップします。興味のないコードのスキップセクションを参照してください。
  • trace - 診断出力を有効にします。

これらの属性は、リクエスト タイプ launch の起動構成でのみ使用できます。

  • program - デバッグする Node.js プログラムへの絶対パス。
  • args - デバッグするプログラムに渡される引数。この属性は配列型であり、個々の引数を配列要素として期待します。
  • cwd - このディレクトリでデバッグするプログラムを起動します。
  • runtimeExecutable - 使用するランタイム実行可能ファイルへの絶対パス。デフォルトは node です。「npm」およびその他のツールに対する起動構成のサポートセクションを参照してください。
  • runtimeArgs - ランタイム実行可能ファイルに渡されるオプションの引数。
  • runtimeVersion - Node.js バージョンの管理に「nvm」(または「nvm-windows」)または「nvs」が使用されている場合、この属性を使用して特定の Node.js バージョンを選択できます。複数バージョンサポートセクションを参照してください。
  • env - オプションの環境変数。この属性は、文字列型キー/値ペアのリストとして環境変数を期待します。
  • envFile - 環境変数定義を含むファイルへのオプションのパス。外部ファイルから環境変数を読み込むセクションを参照してください。
  • console - プログラムを起動するコンソール (internalConsoleintegratedTerminalexternalTerminal)。Node コンソールセクションを参照してください。
  • outputCapture - std に設定すると、デバッグ ポート経由で出力をリッスンする代わりに、プロセスの stdout/stderr からの出力がデバッグ コンソールに表示されます。これは、console.* API を使用する代わりに、stdout/stderr ストリームに直接書き込むプログラムやログ ライブラリに役立ちます。

この属性は、リクエスト タイプ attach の起動構成でのみ使用できます。

  • restart - 終了時に接続を再起動します。デバッグセッションの自動再起動セクションを参照してください。
  • port - 使用するデバッグ ポート。Node.js へのアタッチリモート デバッグセクションを参照してください。
  • address - デバッグ ポートの TCP/IP アドレス。Node.js へのアタッチリモート デバッグセクションを参照してください。
  • processId - デバッガーは USR1 シグナルを送信した後、このプロセスにアタッチしようとします。この設定を使用すると、デバッガーはデバッグ モードで開始されていない、すでに実行中のプロセスにアタッチできます。processId 属性を使用する場合、デバッグ ポートは Node.js バージョン (および使用されるプロトコル) に基づいて自動的に決定され、明示的に構成することはできません。したがって、port 属性は指定しないでください。
  • continueOnAttach - アタッチしたときにプロセスが一時停止している場合、続行するかどうか。このオプションは、--inspect-brk でプログラムを起動する場合に便利です。

一般的なシナリオの起動構成

launch.json ファイルで IntelliSense (⌃Space (Windows、Linux Ctrl+Space)) をトリガーすると、一般的に使用される Node.js デバッグ シナリオの起動構成スニペットが表示されます。

Launch configuration snippets for Node.js

launch.json エディター ウィンドウの右下にある構成の追加...ボタンでスニペットを表示することもできます。

Add Configuration button

次のスニペットが利用可能です。

  • プログラムの起動: Node.js プログラムをデバッグモードで起動します。
  • npm を介して起動: npm の「デバッグ」スクリプトを介して Node.js プログラムを起動します。package.json で定義されている場合、起動構成から npm デバッグスクリプトを使用できます。npm スクリプトで使用されるデバッグポートは、スニペットで指定されたポートに対応している必要があります。
  • アタッチ: ローカルで実行中の Node.js プログラムのデバッグポートにアタッチします。デバッグする Node.js プログラムがデバッグモードで起動されており、使用されているデバッグポートがスニペットで指定されているものと同じであることを確認してください。
  • リモートプログラムにアタッチ: address 属性で指定されたホストで実行中の Node.js プログラムのデバッグポートにアタッチします。デバッグする Node.js プログラムがデバッグモードで起動されており、使用されているデバッグポートがスニペットで指定されているものと同じであることを確認してください。VS Code がワークスペースとリモートホストのファイルシステム間でソースファイルをマップできるように、localRoot および remoteRoot 属性に正しいパスを指定してください。
  • プロセス ID でアタッチ: プロセス ピッカーを開いて、デバッグする node または gulp プロセスを選択します。この起動構成を使用すると、デバッグ モードで起動されていない node または gulp プロセスにもアタッチできます。
  • Nodemon セットアップ: JavaScript ソースが変更されるたびに、nodemon を使用してデバッグセッションを自動的に再起動します。nodemon がグローバルにインストールされていることを確認してください。デバッグセッションを終了しても、デバッグするプログラムが終了するだけで、nodemon 自体は終了しないことに注意してください。nodemon を終了するには、統合ターミナルで Ctrl+C を押します。
  • Mocha テスト: プロジェクトの test フォルダーにある Mocha テストをデバッグします。プロジェクトの node_modules フォルダーに「mocha」がインストールされていることを確認してください。
  • Yeoman ジェネレーター: Yeoman ジェネレーターをデバッグします。このスニペットは、ジェネレーターの名前を指定するよう求めます。プロジェクトの node_modules フォルダーに「yo」がインストールされており、生成されたプロジェクトがプロジェクト フォルダーで npm link を実行することでデバッグ用にインストールされていることを確認してください。
  • Gulp タスク: Gulp タスクをデバッグします。プロジェクトの node_modules フォルダーに「gulp」がインストールされていることを確認してください。
  • Electron Main: Electron アプリケーションのメイン Node.js プロセスをデバッグします。このスニペットは、Electron 実行可能ファイルがワークスペースの node_modules/.bin ディレクトリ内にインストールされていることを前提としています。

Node コンソール

デフォルトでは、Node.js デバッグセッションはターゲットを VS Code の内部デバッグコンソールで起動します。デバッグコンソールはコンソールからの入力を読み取る必要があるプログラムをサポートしないため、起動構成の console 属性をそれぞれ externalTerminal または integratedTerminal に設定することで、外部ターミナルを有効にするか、VS Code 統合ターミナルを使用できます。デフォルトは internalConsole です。

外部ターミナルでは、terminal.external.windowsExecterminal.external.osxExec、および terminal.external.linuxExec 設定を介して使用するターミナルプログラムを構成できます。

「npm」およびその他のツールに対する起動構成のサポート

Node.js プログラムを node で直接起動する代わりに、「npm」スクリプトやその他のタスクランナーツールを起動構成から直接使用できます。

  • runtimeExecutable 属性には PATH 上で利用可能な任意のプログラム (例: 「npm」、「mocha」、「gulp」など) を使用でき、引数は runtimeArgs を介して渡すことができます。
  • npm スクリプトまたはその他のツールが起動するプログラムを暗黙的に指定している場合、program 属性を設定する必要はありません。

「npm」の例を見てみましょう。package.json に「debug」スクリプトがある場合、たとえば

  "scripts": {
    "debug": "node myProgram.js"
  },

対応する起動構成は次のようになります。

{
  "name": "Launch via npm",
  "type": "node",
  "request": "launch",
  "cwd": "${workspaceFolder}",
  "runtimeExecutable": "npm",
  "runtimeArgs": ["run-script", "debug"]
}

複数バージョンサポート

Node.js バージョンを管理するために「nvm」(または「nvm-windows」)を使用している場合、特定の Node.js バージョンを選択するための runtimeVersion 属性を起動構成で指定できます。

{
  "type": "node",
  "request": "launch",
  "name": "Launch test",
  "runtimeVersion": "14",
  "program": "${workspaceFolder}/test.js"
}

Node.js バージョンを管理するために「nvs」を使用している場合、runtimeVersion 属性を使用して特定のバージョン、アーキテクチャ、フレーバーの Node.js を選択できます。

{
  "type": "node",
  "request": "launch",
  "name": "Launch test",
  "runtimeVersion": "chackracore/8.9.4/x64",
  "program": "${workspaceFolder}/test.js"
}

この機能はバージョンを自動的にダウンロードしてインストールしないため、runtimeVersion 属性で使用したい Node.js バージョンがインストールされていることを確認してください。たとえば、起動構成に "runtimeVersion": "7.10.1" を追加する予定がある場合、統合ターミナルから nvm install 7.10.1 または nvs add 7.10.1 のようなコマンドを実行する必要があります。

マイナーバージョンとパッチバージョンを省略し、たとえば "runtimeVersion": "14" とした場合、システムにインストールされている最新の 14.x.y バージョンが使用されます。

外部ファイルから環境変数を読み込む

VS Code の Node デバッガーは、ファイルから環境変数を読み込み、それらを Node.js ランタイムに渡すことをサポートしています。この機能を使用するには、起動構成に envFile 属性を追加し、環境変数を含むファイルへの絶対パスを指定します。

   //...
   "envFile": "${workspaceFolder}/.env",
   "env": { "USER": "john doe" }
   //...

env ディクショナリで指定された環境変数は、ファイルから読み込まれた変数を上書きします。

.env ファイルの例を次に示します。

USER=doe
PASSWORD=abc123

# a comment

# an empty value:
empty=

# new lines expanded in quoted strings:
lines="foo\nbar"

Node.js へのアタッチ

VS Code デバッガーを外部の Node.js プログラムにアタッチしたい場合は、次のように Node.js を起動します。

node --inspect program.js

または、プログラムが実行を開始せず、デバッガーがアタッチされるのを待つ必要がある場合

node --inspect-brk program.js

デバッガーをプログラムにアタッチするオプション

  • すべての潜在的な候補プロセスをリストし、1 つを選択できる「プロセス ピッカー」を開くか、
  • すべての構成オプションを明示的に指定する「アタッチ」構成を作成し、F5 を押します。

これらのオプションについて詳しく見ていきましょう。

Node プロセスへのアタッチアクション

コマンド パレット (⇧⌘P (Windows, Linux Ctrl+Shift+P)) からのNode プロセスへのアタッチコマンドは、Node.js デバッガーで利用可能なすべての潜在的なプロセスをリストするクイック ピック メニューを開きます。

Node.js Process picker

ピッカーにリストされている個々のプロセスには、デバッグポートとプロセス ID が表示されます。そのリストで Node.js プロセスを選択すると、Node.js デバッガーはそれにアタッチしようとします。

Node.js プロセスに加えて、ピッカーはさまざまな形式の --inspect 引数で起動された他のプログラムも表示します。これにより、Electron または VS Code のヘルパープロセスにアタッチすることができます。

「アタッチ」構成のセットアップ

このオプションはより多くの作業が必要ですが、以前の 2 つのオプションとは異なり、さまざまなデバッグ構成オプションを明示的に構成できます。

最も簡単な「アタッチ」構成は次のようになります。

{
  "name": "Attach to Process",
  "type": "node",
  "request": "attach",
  "port": 9229
}

ポート 9229 は、--inspect および --inspect-brk オプションのデフォルトのデバッグ ポートです。別のポート (例: 12345) を使用するには、--inspect=12345 および --inspect-brk=12345 のようにオプションに追加し、起動構成の port 属性を一致するように変更します。

デバッグモードで開始されていない Node.js プロセスにアタッチするには、Node.js プロセスのプロセス ID を文字列として指定することで可能です。

{
  "name": "Attach to Process",
  "type": "node",
  "request": "attach",
  "processId": "53426"
}

起動構成で新しいプロセス ID を繰り返し入力するのを避けるため、Node デバッグはプロセス ピッカー (上記) を開くコマンド変数 PickProcess をサポートしています。

PickProcess 変数を使用すると、起動構成は次のようになります。

{
  "name": "Attach to Process",
  "type": "node",
  "request": "attach",
  "processId": "${command:PickProcess}"
}

デバッグを停止する

デバッグ: 停止アクション (デバッグ ツールバーまたはコマンド パレットから利用可能) を使用すると、デバッグ セッションが停止します。

デバッグ セッションが「アタッチ」モードで開始された場合 (デバッグ ツールバーの赤い終了ボタンに「プラグ」が重ねて表示されている場合)、停止を押すと Node.js デバッガーがデバッグ対象から切断され、実行が続行されます。

デバッグ セッションが「起動」モードの場合、停止を押すと次のようになります。

  1. 最初に停止を押すと、SIGINT シグナルを送信してデバッグ対象に正常なシャットダウンを要求します。デバッグ対象は、このシグナルをインターセプトして必要に応じてクリーンアップし、シャットダウンすることができます。そのシャットダウン コードにブレークポイント (または問題) がなければ、デバッグ対象とデバッグ セッションは終了します。

  2. ただし、デバッガーがシャットダウン コードでブレークポイントにヒットした場合、またはデバッグ対象がそれ自体で適切に終了しない場合、デバッグセッションは終了しません。この場合、再度停止を押すと、デバッグ対象とその子プロセスが強制終了されます (SIGKILL)。

赤い停止ボタンを押してもデバッグ セッションが終了しない場合は、もう一度ボタンを押してデバッグ対象を強制的にシャットダウンしてください。

Windows では、停止を押すと、デバッグ対象とその子プロセスが強制的に終了します。

ソースマップ

VS Code の JavaScript デバッガーは、トランスパイルされた言語、たとえば TypeScript や縮小/難読化された JavaScript のデバッグを支援するソースマップをサポートしています。ソースマップを使用すると、元のソースで単一ステップ実行したり、ブレークポイントを設定したりできます。元のソースにソースマップが存在しない場合、またはソースマップが壊れていてソースと生成された JavaScript の間を正常にマッピングできない場合、ブレークポイントは未検証 (灰色の空の円) として表示されます。

デフォルトで true に設定されている sourceMaps 属性がソースマップ機能を制御します。デバッガーは常にソースマップを使用しようとします (見つかる場合) その結果、program 属性でソースファイル (たとえば app.ts) を指定することもできます。何らかの理由でソースマップを無効にする必要がある場合は、sourceMaps 属性を false に設定できます。

ツール構成

ソースマップは常に自動的に作成されるわけではないため、トランスパイラーがソースマップを作成するように構成する必要があります。たとえば、

TypeScript

TypeScript の場合、tsc--sourceMap を渡すか、tsconfig.json ファイルに "sourceMap": true を追加することで、ソースマップを有効にできます。

tsc --sourceMap --outDir bin app.ts

Babel

Babel の場合、sourceMaps オプションを true に設定するか、コードをコンパイルするときに --source-maps オプションを渡す必要があります。

npx babel script.js --out-file script-compiled.js --source-maps

Webpack

Webpack には多数のソースマップオプションがあります。ビルドの速度低下を引き起こす他の設定を試すこともできますが、最良の結果を得るには、webpack.config.jsdevtool: "source-map" プロパティを設定することをお勧めします。

また、TypeScript ローダーを使用するなど、Webpack に追加のコンパイル ステップがある場合は、それらのステップもソースマップを生成するように設定されていることを確認する必要があります。そうしないと、Webpack が生成するソースマップは、実際のソースではなく、ローダーからのコンパイル済みコードにマッピングされてしまいます。

ソースマップの検出

デフォルトでは、VS Code はワークスペース全体から node_modules を除外してソースマップを検索します。大規模なワークスペースでは、この検索に時間がかかる場合があります。launch.jsonoutFiles 属性を設定することで、VS Code がソースマップを検索する場所を構成できます。たとえば、この構成では、bin フォルダー内の .js ファイルのソースマップのみが検出されます。

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch TypeScript",
      "type": "node",
      "request": "launch",
      "program": "app.ts",
      "outFiles": ["${workspaceFolder}/bin/**/*.js"]
    }
  ]
}

outFiles は、JavaScript ファイルに一致する必要があることに注意してください (ソースマップ ファイルは .js ではなく .map で終わる場合があります)。

ソースマップ解決

デフォルトでは、outFiles 内のソースマップのみが解決されます。この動作は、依存関係が設定したブレークポイントと干渉するのを防ぐために使用されます。たとえば、src/index.ts というファイルがあり、依存関係に webpack:///./src/index.ts を参照するソースマップがある場合、それはソースファイルに誤って解決され、予期しない結果につながる可能性があります。

resolveSourceMapLocations オプションを設定することで、この動作を構成できます。null に設定すると、すべてのソースマップが解決されます。たとえば、この構成では、node_modules/some-dependency 内のソースマップも解決できるようになります。

  "resolveSourceMapLocations": [
    "out/**/*.js",
    "node_modules/some-dependency/**/*.js",
  ]

スマートステップ

起動構成で smartStep 属性を true に設定すると、デバッガーでコードをステップ実行する際に、VS Code は「興味のないコード」を自動的にスキップします。「興味のないコード」とは、トランスパイルプロセスによって生成されたコードであるが、ソースマップでカバーされていないため、元のソースにマッピングされないコードです。このコードは、デバッガーでソースコードをステップ実行する際に邪魔になります。なぜなら、デバッガーが元のソースコードと興味のない生成されたコードの間を切り替えるようにするためです。smartStep は、ソースマップでカバーされていないコードを自動的にステップ実行し、再びソースマップでカバーされている場所に到達するまで続きます。

スマートステップは、コンパイラがソースマップでカバーされていないヘルパーコードを挿入する TypeScript の async/await のダウンコンパイルなどの場合に特に役立ちます。

smartStep 機能は、ソースから生成された JavaScript コードにのみ適用され、そのためソースマップを持っています。ソースのない JavaScript の場合、スマートステップオプションは効果がありません。

JavaScript ソースマップのヒント

ソースマップでデバッグする際のよくある問題は、ブレークポイントを設定してもそれが灰色になることです。カーソルを重ねると、「"Breakpoint ignored because generated code not found (source map problem?)"」というメッセージが表示されます。さて、どうすればよいでしょうか?これにはさまざまな問題が考えられます。まず、Node デバッグアダプターがソースマップをどのように処理するかについて簡単に説明します。

app.ts にブレークポイントを設定すると、デバッグアダプターは、TypeScript ファイルをトランスパイルしたバージョンである app.js へのパスを特定する必要があります。これは実際に Node で実行されているものです。しかし、.ts ファイルからこれを特定する簡単な方法はありません。代わりに、デバッグアダプターは launch.jsonoutFiles 属性を使用して、トランスパイルされたすべての .js ファイルを見つけ、それらを解析してソースマップを見つけます。ソースマップには、関連する .ts ファイルの場所が含まれています。

ソースマップを有効にして TypeScript で app.ts ファイルをビルドすると、app.js.map ファイルが生成されるか、app.js ファイルの末尾のコメントに base64 エンコードされた文字列としてソースマップがインライン化されます。このマップに関連付けられた .ts ファイルを見つけるために、デバッグアダプターはソースマップ内の sourcessourceRoot の 2 つのプロパティを調べます。sourceRoot はオプションです。存在する場合は、sources (パスの配列) の各パスの前に付加されます。結果は、.ts ファイルへの絶対パスまたは相対パスの配列になります。相対パスは、ソースマップに対して解決されます。

最後に、デバッグアダプターは、結果の .ts ファイルのリストで app.ts のフルパスを検索します。一致するものがあれば、app.tsapp.js にマッピングするときに使用するソースマップファイルが見つかったことになります。一致するものがない場合、ブレークポイントをバインドできず、灰色に変わります。

ブレークポイントが灰色に変わったときに試すことをいくつかご紹介します。

  • デバッグ中に、デバッグ: ブレークポイントの問題を診断コマンドを実行します。このコマンドは、コマンド パレット (⇧⌘P (Windows, Linux Ctrl+Shift+P)) から問題を解決するのに役立つヒントを提供できるツールを起動します。
  • ソースマップを有効にしてビルドしましたか?.js.map ファイル、または .js ファイルにインラインソースマップがあることを確認してください。
  • ソースマップの sourceRoot および sources プロパティは正しいですか?それらを組み合わせて .ts ファイルへの正しいパスを取得できますか?
  • VS Code でフォルダを間違った大文字/小文字で開いていませんか?コマンドラインから code FOO のようにフォルダ foo/ を開くことが可能で、その場合ソースマップが正しく解決されない場合があります。
  • Stack Overflow で特定のセットアップに関するヘルプを検索するか、GitHub で問題を提出してみてください。
  • debugger ステートメントを追加してみてください。そこで .ts ファイルにブレークするが、その場所のブレークポイントがバインドしない場合、それは GitHub の問題に含める有用な情報です。

ソースマップパスのオーバーライド

デバッガーは sourceMapPathOverrides を使用して、カスタムのソースマップからディスクへのパスマッピングを実装します。ほとんどのツールには優れたデフォルトが設定されていますが、高度なケースではカスタマイズが必要になる場合があります。デフォルトのパスオーバーライドは次のようなオブジェクトマップです。

{
  'webpack:///./~/*': "${workspaceFolder}/node_modules/*",
  'webpack:////*': '/*',
  'webpack://@?:*/?:*/*': "${workspaceFolder}/*",
  // and some more patterns...
}

これは、ソースマップ内のパスまたは URL を左から右にマッピングします。パターン ?:* は非貪欲な非キャプチャマッチであり、* は貪欲なキャプチャマッチです。デバッガーは、右側のパターン内の対応する * を、ソースマップパスからキャプチャされたフラグメントに置き換えます。たとえば、上記の例の最後のパターンは、webpack://@my/package/foo/bar${workspaceFolder}/foo/bar にマッピングします。

ブラウザのデバッグでは、デフォルトの sourceMapPathOverridesworkspaceFolder の代わりに webRoot が使用されることに注意してください。

リモートデバッグ

注: VS Code には、現在ユニバーサルなリモート開発機能があります。リモート開発拡張機能を使用すると、リモートシナリオやコンテナでの Node.js 開発は、ローカル環境での Node.js 開発と何ら変わりありません。これは、Node.js プログラムをリモートデバッグするための推奨される方法です始めにセクションとリモートチュートリアルを参照して詳細をご覧ください。

リモート開発拡張機能のいずれも使用して Node.js プログラムをデバッグできない場合は、VS Code のローカルインスタンスからリモート Node.js プログラムをデバッグする方法に関するガイドを以下に示します。

Node.js デバッガーは、別のマシンまたはコンテナで実行されているプロセスにアタッチするリモートデバッグをサポートしています。address 属性を介してリモートホストを指定します。たとえば、

{
  "type": "node",
  "request": "attach",
  "name": "Attach to remote",
  "address": "192.168.148.2", // <- remote address here
  "port": 9229
}

デフォルトでは、VS Code はリモート Node.js フォルダーからローカル VS Code にデバッグされたソースをストリーミングし、読み取り専用エディターに表示します。このコードをステップ実行できますが、変更することはできません。VS Code が代わりにワークスペースから編集可能なソースを開くようにしたい場合は、リモートとローカルの場所の間のマッピングを設定できます。localRootremoteRoot 属性を使用して、ローカル VS Code プロジェクトと (リモート) Node.js フォルダー間のパスをマッピングできます。これは、同じシステム上または異なるオペレーティングシステム間でローカルでも機能します。コードパスをリモート Node.js フォルダーからローカル VS Code パスに変換する必要があるたびに、remoteRoot パスはパスから削除され、localRoot に置き換えられます。逆変換の場合、localRoot パスは remoteRoot に置き換えられます。

{
  "type": "node",
  "request": "attach",
  "name": "Attach to remote",
  "address": "TCP/IP address of process to be debugged",
  "port": 9229,
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "C:\\Users\\username\\project\\server"
}

読み込まれたスクリプトへのアクセス

ワークスペースの一部ではないため、通常の VS Code ファイル参照では簡単に見つけて開くことができないスクリプトにブレークポイントを設定する必要がある場合は、実行とデバッグビューの読み込まれたスクリプトビューから読み込まれたスクリプトにアクセスできます。

Loaded Scripts Explorer

読み込まれたスクリプトビューでは、名前を入力してスクリプトをすばやく選択したり、タイプでフィルタリングを有効にするがオンになっているときにリストをフィルタリングしたりできます。

スクリプトは読み取り専用エディターに読み込まれ、そこでブレークポイントを設定できます。これらのブレークポイントはデバッグセッション全体で記憶されますが、スクリプトコンテンツへのアクセスはデバッグセッションが実行されている間のみ可能です。

ソース編集時のデバッグセッション自動再起動

起動構成の restart 属性は、デバッグセッションが終了した後に Node.js デバッガーが自動的に再起動するかどうかを制御します。この機能は、ファイル変更時に Node.js を再起動するためにnodemonを使用している場合に便利です。起動構成属性 restarttrue に設定すると、Node.js が終了した後、node デバッガーは自動的に Node.js に再アタッチしようとします。

コマンドラインで nodemon を介して server.js プログラムを次のように開始した場合、

nodemon --inspect server.js

次の起動構成を使用して、VS Code デバッガーをそれにアタッチできます。

{
  "name": "Attach to node",
  "type": "node",
  "request": "attach",
  "restart": true,
  "port": 9229
}

あるいは、起動構成を使って nodemon で直接 server.js プログラムを開始し、VS Code デバッガーをアタッチすることもできます。

{
  "name": "Launch server.js via nodemon",
  "type": "node",
  "request": "launch",
  "runtimeExecutable": "nodemon",
  "program": "${workspaceFolder}/server.js",
  "console": "integratedTerminal",
  "internalConsoleOptions": "neverOpen"
}

ヒント: 停止ボタンを押すと、デバッグセッションが停止し、Node.js から切断されますが、nodemon (および Node.js) は引き続き実行されます。nodemon を停止するには、コマンドラインから強制終了する必要があります (上記のように integratedTerminal を使用している場合は簡単に可能です)。

ヒント: 構文エラーの場合、エラーが修正されるまで nodemon は Node.js を正常に開始できません。この場合、VS Code は Node.js へのアタッチを試行し続けますが、最終的に (10 秒後に) あきらめます。これを避けるには、timeout 属性に大きな値 (ミリ秒単位) を追加してタイムアウトを増やします。

フレームを再起動する

Node デバッガーは、スタックフレームでの実行の再開をサポートしています。これは、ソースコードに問題が見つかり、変更された入力値でコードの一部を再実行したい場合に役立ちます。完全なデバッグセッションを停止して再開するのは時間がかかる場合があります。フレームを再起動アクションを使用すると、値を設定アクションで変数を変更した後、現在の関数を再入力できます。

Restart frame

フレームを再起動は、関数の外部の状態への変更を元に戻すことはないため、常に期待どおりに機能するとは限りません。

Breakpoints

条件付きブレークポイント

条件付きブレークポイントは、式が真値を返す場合にのみ一時停止するブレークポイントです。行番号の横のガターを右クリックし、「条件付きブレークポイント」を選択して作成できます。

Conditional breakpoint

ログポイント

特定の場所にコードが到達したときに、一時停止するのではなく、単にメッセージや値をログに記録したい場合があります。これはログポイントで実行できます。ログポイントは一時停止しませんが、ヒットしたときにデバッグコンソールにメッセージをログに記録します。JavaScript デバッガーでは、中括弧を使用して式をメッセージに補間できます。たとえば、current value is: {myVariable.property} のようにです。

行番号の横のガターを右クリックし、「ログポイント」を選択して作成できます。たとえば、これは location is /usr/local のようなものをログに記録する可能性があります。

Logpoint

ヒットカウントブレークポイント

「ヒットカウント条件」は、ブレークポイントが実行を「中断」するまでに何回ヒットする必要があるかを制御します。行番号の横のガターを右クリックし、「条件付きブレークポイント」を選択し、「ヒットカウント」に切り替えることで、ヒットカウントブレークポイントを設定できます。

Hit count breakpoint

Node.js デバッガーでサポートされているヒットカウントの構文は、整数、または <<===>>=% のいずれかの演算子の後に整数が続くものです。

いくつかの例

  • >10 10 回ヒットした後は常にブレークする
  • <3 最初の 2 回のヒットでのみブレークする
  • 10 >=10 と同じ
  • %2 2 回に 1 回ブレークする

トリガーされたブレークポイント

トリガーされたブレークポイントとは、別のブレークポイントに到達すると自動的に有効になるブレークポイントです。これらは、特定の事前条件の後にのみ発生するコードの失敗ケースを診断する際に非常に役立ちます。

トリガーされたブレークポイントは、グリフマージンを右クリックし、トリガーされたブレークポイントの追加を選択し、その後、どの他のブレークポイントがこのブレークポイントを有効にするかを選択することで設定できます。

ブレークポイント検証

パフォーマンス上の理由から、Node.js は JavaScript ファイル内の関数を最初にアクセスしたときに遅延解析します。結果として、Node.js にまだ認識されていない (解析されていない) ソースコード領域ではブレークポイントが機能しません。

この動作はデバッグには理想的ではないため、VS Code は --nolazy オプションを自動的に Node.js に渡します。これにより、遅延解析が防止され、コードを実行する前にブレークポイントを検証できるようになります (そのため、ブレークポイントが「ジャンプ」しなくなります)。

--nolazy オプションはデバッグターゲットの起動時間を大幅に増加させる可能性があるため、runtimeArgs 属性として --lazy を渡すことで簡単にオプトアウトできます。

そのようにすると、ブレークポイントの一部が要求された行に「固定」されず、代わりにすでに解析されたコードの次の可能な行に「ジャンプ」することがわかります。混乱を避けるため、VS Code は常に Node.js がブレークポイントであると考える位置にブレークポイントを表示します。ブレークポイントセクションでは、これらのブレークポイントは要求された行番号と実際の行番号の間に矢印で表示されます。

Breakpoints View

このブレークポイント検証は、セッションが開始され、ブレークポイントが Node.js に登録されたとき、またはセッションがすでに実行中で新しいブレークポイントが設定されたときに発生します。この場合、ブレークポイントは別の場所に「ジャンプ」する可能性があります。Node.js がすべてのコードを解析した後 (たとえば、実行した後)、ブレークポイントセクションヘッダーの再適用ボタンを使用して、ブレークポイントを要求された場所に簡単に再適用できます。これにより、ブレークポイントは要求された場所に「ジャンプバック」するはずです。

Breakpoint Actions

興味のないコードのスキップ

VS Code Node.js デバッグには、ステップ実行したくないソースコードを避ける機能 (「Just My Code」とも呼ばれます) があります。この機能は、起動構成の skipFiles 属性で有効にできます。skipFiles は、スキップするスクリプトパスのグロブ パターンの配列です。

例えば、以下を使用すると

  "skipFiles": [
    "${workspaceFolder}/node_modules/**/*.js",
    "${workspaceFolder}/lib/**/*.js"
  ]

プロジェクトの node_modules および lib フォルダー内のすべてのコードがスキップされます。skipFilesconsole.log および同様のメソッドを呼び出すときに表示される場所にも適用されます。スタック内の最初のスキップされていない場所がデバッグコンソールの出力の横に表示されます。

Node.js の組み込みのコアモジュールは、グロブ パターンの「マジック名」<node_internals> で参照できます。次の例では、すべての内部モジュールをスキップします。

  "skipFiles": [
     "<node_internals>/**/*.js"
   ]

厳密な「スキップ」ルールは次のとおりです。

  • スキップされたファイルにステップインしても、そこで停止しません。スキップされていないファイル内の次の実行された行で停止します。
  • スローされた例外でブレークするオプションを設定している場合、スキップされたファイルからスローされた例外は、スキップされていないファイルにバブルアップしない限り、ブレークしません。
  • スキップされたファイルにブレークポイントを設定した場合、そのブレークポイントで停止し、そこからステップアウトするまでステップ実行できます。その時点で通常のスキップ動作が再開されます。
  • スキップファイル内のコンソールメッセージの場所は、コールスタック内の最初のスキップされていない場所として表示されます。

スキップされたソースは、コールスタックビューで「薄暗い」スタイルで表示されます。

Skipped source is dimmed in call stack view

薄暗いエントリにカーソルを合わせると、スタックフレームが薄暗い理由が説明されます。

コールスタックのコンテキストメニュー項目であるこのファイルをスキップする/しないを使用すると、起動構成に追加することなく、実行時にファイルを簡単にスキップできます。このオプションは、現在のデバッグセッションの間のみ有効です。また、起動構成の skipFiles オプションでスキップされているファイルのスキップを停止するためにも使用できます。

注: legacy プロトコルデバッガーは負のグロブ パターンをサポートしていますが、正のパターンの後に続く必要があります。正のパターンはスキップされたファイルのセットに追加され、負のパターンはそのセットから減算されます。

次の (legacy プロトコルのみの) 例では、「math」モジュールを除くすべてがスキップされます。

"skipFiles": [
    "${workspaceFolder}/node_modules/**/*.js",
    "!${workspaceFolder}/node_modules/math/**/*.js"
]

注: legacy プロトコルデバッガーは、V8 デバッガープロトコルがネイティブにサポートしていないため、skipFiles 機能をエミュレートする必要があります。これにより、ステップ実行のパフォーマンスが低下する可能性があります。

WebAssembly のデバッグ

JavaScript デバッガーは、DWARF デバッグ情報を含む場合に、WebAssembly にコンパイルされたコードをデバッグできます。多くのツールチェーンがこの情報の出力に対応しています。

  • Emscripten を使用した C/C++: デバッグ情報を出力するために -g フラグを付けてコンパイルします。
  • Zig: DWARF 情報は「Debug」ビルドモードで自動的に出力されます。
  • Rust: Rust は DWARF デバッグ情報を出力します。しかし、wasm-pack はビルド中にまだ保持していません (issue #1351)。したがって、一般的な wasm-bindgen/wasm-pack ライブラリのユーザーは、wasm-pack build を実行する代わりに、2 つのコマンドを使用して手動でビルドする必要があります。
    1. 必要なコマンドラインツールをインストールするために、cargo install wasm-bindgen-cli を一度実行します。
    2. ライブラリをビルドするために、cargo build --target wasm32-unknown-unknown を実行します。
    3. wasm-bindgen --keep-debug --out-dir pkg ./target/wasm32-unknown-unknown/debug/<library-name>.wasm <extra-arguments> を実行して WebAssembly バインディングを生成します。<library-name> を Cargo.toml の名前で置き換え、必要に応じて <extra-arguments> を設定します。

コードをビルドしたら、WebAssembly DWARF Debugging 拡張機能をインストールする必要があります。これは、VS Code のコアを「合理化」するために、別の拡張機能として提供されています。インストール後、アクティブなデバッグセッションを再起動すると、ネイティブコードがデバッガーにマッピングされるはずです!ロード済みソースビューにソースコードが表示され、ブレークポイントが機能するはずです。

下の画像では、デバッガーはマンデルブロ集合を生成する C++ ソースコードのブレークポイントで停止しています。JavaScript コード、WebAssembly、マップされた C++ コードのフレームを含むコールスタックが表示されています。C++ コードの変数と、int32 height 変数に関連付けられたメモリへの編集も確認できます。

Debugger stopped on a breakpoint in C++ source code

同等に近いですが、WebAssembly のデバッグは通常の JavaScript とは少し異なります。

  • 変数ビューの変数は直接編集できません。ただし、変数の横にあるバイナリデータを表示アクションを選択して、関連するメモリを編集できます。
  • デバッグ コンソールおよびウォッチビューでの基本的な式評価は、lldb-eval によって提供されます。これは通常の JavaScript 式とは異なります。
  • ソースコードにマップされていない場所は、逆アセンブルされた WebAssembly テキスト形式で表示されます。WebAssembly の場合、コマンドソースマップ ステップを無効にするを実行すると、デバッガーは逆アセンブルされたコードのみをステップ実行します。

VS Code の WebAssembly デバッグは、Chromium 作者のC/C++ Debugging Extensionに基づいています。

サポートされている Node に似たランタイム

現在の VS Code JavaScript デバッガーは、Node 8.x 以降のバージョン、最近の Chrome バージョン、および最近の Edge バージョン (msedge 起動タイプ経由) をサポートしています。

次のステップ

まだ Node.js のセクションを読んでいない場合は、以下をご覧ください。

  • Node.js - サンプルアプリケーションによるエンドツーエンドの Node シナリオ

VS Code でのデバッグの基本に関するチュートリアルは、このビデオをご覧ください。

VS Code のタスク実行サポートについては、以下をご覧ください。

  • タスク - Gulp、Grunt、Jake を使用したタスクの実行。エラーと警告の表示

独自のデバッガー拡張機能を記述するには、以下をご覧ください。

よくある質問

はい、npm link などでプロジェクト内にシンボリックリンクを作成した場合、Node.js ランタイムにシンボリックリンクされたパスを保持するように指示することで、シンボリックリンクされたソースをデバッグできます。起動構成の runtimeArgs 属性で node.exe の --preserve-symlinks スイッチを使用します。文字列の配列である runtimeArgs は、デバッグセッションのランタイム実行可能ファイル (デフォルトは node.exe) に渡されます。

{
  "runtimeArgs": ["--preserve-symlinks"]
}

メインスクリプトがシンボリックリンクされたパス内にある場合、"--preserve-symlinks-main" オプションも追加する必要があります。このオプションは Node 10+ でのみ利用可能です。

ECMAScript モジュールをデバッグするにはどうすればよいですか?

ECMAScript モジュールを使用するために esm を使用するか、Node.js に --experimental-modules を渡す場合、これらのオプションを launch.jsonruntimeArgs 属性を介して渡すことができます。

NODE_OPTIONS を設定するにはどうすればよいですか?

デバッガーは特殊な NODE_OPTIONS 環境変数を使用してアプリケーションでのデバッグを設定し、これを上書きするとデバッグが正しく機能しなくなります。上書きするのではなく、追加する必要があります。たとえば、.bashrc ファイルには次のようなものが含まれる場合があります。

export NODE_OPTIONS="$NODE_OPTIONS --some-other-option=here"
© . This site is unofficial and not affiliated with Microsoft.