Node.js のデバッグ
このガイドは、Node.js アプリやスクリプトのデバッグを始めるのに役立ちます。
インスペクタの有効化
--inspect スイッチ付きで起動すると、Node.js プロセスはデバッグクライアントを待ち受けます。デフォルトでは、ホストとポート 127.0.0.1:9229 で待ち受けます。各プロセスには、一意の UUID も割り当てられます。
インスペクタクライアントは、接続するためにホストアドレス、ポート、UUID を知って指定する必要があります。完全な URL は ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e のようになります。
Node.js は SIGUSR1 シグナルを受信した場合にもデバッグメッセージの待ち受けを開始します。(SIGUSR1 は Windows では利用できません。) Node.js 7 以前では、これによりレガシーなデバッガ API が有効になります。Node.js 8 以降では、インスペクタ API が有効になります。
セキュリティへの影響
デバッガは Node.js の実行環境に完全にアクセスできるため、このポートに接続できる悪意のある攻撃者は、Node.js プロセスに代わって任意のコードを実行できる可能性があります。デバッガポートをパブリックおよびプライベートネットワークに公開することのセキュリティ上の影響を理解することが重要です。
デバッグポートを公に公開するのは危険です
デバッガがパブリック IP アドレスまたは 0.0.0.0 にバインドされている場合、あなたの IP アドレスに到達できるクライアントは誰でも制限なくデバッガに接続でき、任意のコードを実行できるようになります。
デフォルトでは、node --inspect は 127.0.0.1 にバインドします。デバッガへの外部接続を許可するつもりなら、パブリック IP アドレスや 0.0.0.0 などを明示的に指定する必要があります。そうすることで、潜在的に重大なセキュリティ脅威にさらされる可能性があります。セキュリティ上の脆弱性を防ぐため、適切なファイアウォールとアクセス制御が設定されていることを確認することをお勧めします。
リモートのデバッガクライアントが安全に接続できるようにするためのアドバイスについては、「リモートデバッグシナリオの有効化」のセクションを参照してください。
ローカルアプリケーションはインスペクタに完全にアクセスできます
インスペクタポートを 127.0.0.1 (デフォルト) にバインドした場合でも、マシン上でローカルに実行されているアプリケーションは無制限にアクセスできます。これは、ローカルのデバッガが便利にアタッチできるように意図された設計です。
ブラウザ、WebSocket、同一オリジンポリシー
ウェブブラウザで開かれたウェブサイトは、ブラウザのセキュリティモデルの下で WebSocket および HTTP リクエストを行うことができます。一意のデバッガセッション ID を取得するには、最初の HTTP 接続が必要です。同一オリジンポリシーは、ウェブサイトがこの HTTP 接続を行うのを防ぎます。DNS リバインディング攻撃に対する追加のセキュリティとして、Node.js は接続の「Host」ヘッダーが IP アドレスまたは localhost を正確に指定していることを検証します。
これらのセキュリティポリシーにより、ホスト名を指定してリモートのデバッグサーバーに接続することはできません。この制限は、IP アドレスを指定するか、以下で説明するように ssh トンネルを使用することで回避できます。
インスペクタクライアント
node inspect myscript.js で最小限の CLI デバッガが利用可能です。いくつかの商用およびオープンソースのツールも Node.js インスペクタに接続できます。
Chrome DevTools 55+、Microsoft Edge
- オプション 1: Chromium ベースのブラウザで
chrome://inspectを開くか、Edge でedge://inspectを開きます。[Configure] ボタンをクリックし、ターゲットのホストとポートがリストされていることを確認します。 - オプション 2:
/json/listの出力 (上記参照) または --inspect のヒントテキストからdevtoolsFrontendUrlをコピーし、Chrome に貼り付けます。
詳細については、https://github.com/ChromeDevTools/devtools-frontend、https://www.microsoftedgeinsider.com を参照してください。
Visual Studio Code 1.10+
- [デバッグ] パネルで、設定アイコンをクリックして
.vscode/launch.jsonを開きます。初期設定のために「Node.js」を選択します。
詳細については、https://github.com/microsoft/vscode を参照してください。
Visual Studio 2017+
- メニューから「デバッグ > デバッグの開始」を選択するか、F5 を押します。
- 詳細な手順.
JetBrains WebStorm およびその他の JetBrains IDE
- 新しい Node.js デバッグ構成を作成し、[Debug] をクリックします。Node.js 7+ では
--inspectがデフォルトで使用されます。無効にするには、IDE レジストリでjs.debugger.node.use.inspectのチェックを外します。WebStorm および他の JetBrains IDE での Node.js の実行とデバッグについて詳しく知るには、WebStorm オンラインヘルプ を参照してください。
chrome-remote-interface
- インスペクタプロトコルのエンドポイントへの接続を容易にするライブラリです。
詳細については、https://github.com/cyrus-and/chrome-remote-interface を参照してください。
Gitpod
Debugビューから Node.js のデバッグ構成を開始するか、F5を押します。詳細な手順
詳細については、https://www.gitpod.io を参照してください。
Eclipse IDE と Eclipse Wild Web Developer 拡張機能
- .js ファイルから、「Debug As... > Node program」を選択するか、
- 実行中の Node.js アプリケーション (既に
--inspectで起動済み) にデバッガをアタッチするためのデバッグ構成を作成します。
詳細については、https://eclipse.org/eclipseide を参照してください。
コマンドラインオプション
以下の表は、さまざまな実行時フラグがデバッグに与える影響を示しています。
| フラグ | 意味 |
|---|---|
| --inspect | インスペクタエージェントを有効にする。デフォルトのアドレスとポート (127.0.0.1:9229) で待ち受ける |
| --inspect=[host:port] | インスペクタエージェントを有効にする。アドレスまたはホスト名 host (デフォルト: 127.0.0.1) にバインドする。ポート port (デフォルト: 9229) で待ち受ける |
| --inspect-brk | インスペクタエージェントを有効にする。デフォルトのアドレスとポート (127.0.0.1:9229) で待ち受ける。ユーザコードが始まる前に中断する |
| --inspect-brk=[host:port] | インスペクタエージェントを有効にする。アドレスまたはホスト名 host (デフォルト: 127.0.0.1) にバインドする。ポート port (デフォルト: 9229) で待ち受ける。ユーザコードが始まる前に中断する |
| --inspect-wait | インスペクタエージェントを有効にする。デフォルトのアドレスとポート (127.0.0.1:9229) で待ち受ける。デバッガがアタッチされるのを待つ。 |
| --inspect-wait=[host:port] | インスペクタエージェントを有効にする。アドレスまたはホスト名 host (デフォルト: 127.0.0.1) にバインドする。ポート port (デフォルト: 9229) で待ち受ける。デバッガがアタッチされるのを待つ。 |
| --disable-sigusr1 | プロセスに SIGUSR1 シグナルを送信してデバッグセッションを開始する機能を無効にする。 |
| node inspect script.js | ユーザのスクリプトを --inspect フラグ付きで実行するために子プロセスを生成し、メインプロセスで CLI デバッガを実行する。 |
| node inspect --port=xxxx script.js | ユーザのスクリプトを --inspect フラグ付きで実行するために子プロセスを生成し、メインプロセスで CLI デバッガを実行する。ポート port (デフォルト: 9229) で待ち受ける |
リモートデバッグシナリオの有効化
デバッガをパブリック IP アドレスで待ち受けさせないことを強くお勧めします。リモートデバッグ接続を許可する必要がある場合は、代わりに ssh トンネルの使用をお勧めします。以下の例は説明のためだけに提供しています。続行する前に、特権サービスへのリモートアクセスを許可することのセキュリティリスクを理解してください。
リモートマシン remote.example.com で Node.js を実行していて、それをデバッグしたいとします。そのマシンで、インスペクタが localhost (デフォルト) のみをリッスンするようにして node プロセスを開始する必要があります。
node --inspect server.js
さて、デバッグクライアント接続を開始したいローカルマシンで、ssh トンネルを設定できます。
ssh -L 9221:localhost:9229 [email protected]
これにより、ローカルマシンのポート 9221 への接続が remote.example.com のポート 9229 に転送される ssh トンネルセッションが開始されます。これで、Chrome DevTools や Visual Studio Code などのデバッガを localhost:9221 にアタッチでき、Node.js アプリケーションがローカルで実行されているかのようにデバッグできるようになります。
レガシーデバッガ
レガシーデバッガは Node.js 7.7.0 で非推奨になりました。代わりに --inspect とインスペクタを使用してください。
バージョン 7 以前で --debug または --debug-brk スイッチ付きで起動すると、Node.js は廃止された V8 デバッグプロトコルで定義されたデバッグコマンドを TCP ポート (デフォルトは 5858) で待ち受けます。このプロトコルを話すデバッガクライアントならどれでも、実行中のプロセスに接続してデバッグできます。人気のあるものをいくつか以下に示します。
V8 デバッグプロトコルはもはやメンテナンスも文書化もされていません。
組み込みデバッガ
node debug script_name.js を実行すると、組み込みのコマンドラインデバッガでスクリプトが開始されます。スクリプトは --debug-brk オプション付きで起動された別の Node.js プロセスで開始され、最初の Node.js プロセスは _debugger.js スクリプトを実行してターゲットに接続します。詳細については、ドキュメント を参照してください。
node-inspector
Chromium で使用される インスペクタプロトコルを Node.js で使用される V8 デバッガプロトコルに変換する中間プロセスを使用して、Node.js アプリを Chrome DevTools でデバッグします。詳細については、https://github.com/node-inspector/node-inspector を参照してください。