できない.dev

VSCode のブレークポイントで止まらない/効かない

実行中プロセスと debugger が attach できていない、sourcemap が壊れていてソース行と実行コードが対応しない、ts-node / tsx の JIT 実行で `outFiles` が未設定、別プロセスで実行され attach 対象から外れている、が典型原因。

#vscode#debugger#breakpoint#launch-json#debug

公開:

要約

ブレークポイントで止まらないときは、ブレークポイントが灰色になっている(attach できていない) か、色付きでも止まらない(行マッピングがずれている) かで原因が分かれる。
前者は launch.json か Auto Attach の問題、後者は sourcemap / outFiles の問題に絞り込める。

よくある原因

  1. launch.json のミスマッチ: programdist/index.js を指しているのに、実際は src/index.tstsx で実行している、というずれ。
    Run and Debug が起動するプロセスが対象でなければ attach は成立しない。
  2. sourcemap 不在: ビルド済 JS に .map が無い、または map が壊れていると、src/foo.ts の 12 行目に置いたブレークポイントを実行コードの 12 行目に対応付けできない。
  3. outFiles 不足: tsx / ts-node 経由のとき、debugger は source への逆引きパスを outFiles から探す。
    これが無いと「ファイルは見えるが止まらない」状態になる。
  4. 別プロセスで実行: メインプロセスに attach していても、child_process.fork で起動した子プロセスや worker thread は別プロセスなので自動では attach されない。

解決策

1. JavaScript Debug Terminal で起動する

Ctrl+Shift+P から Debug: JavaScript Debug Terminal を開き、そのターミナルで npm run dev などを実行する。
専用ターミナルから起動した Node プロセスは自動で attach されるので、launch.json を書かずに切り分けできる(公式の Debugging ドキュメント)。

2. sourcemap を有効にする

// tsconfig.json
{
  "compilerOptions": {
    "sourceMap": true,
    "inlineSources": true
  }
}

Vite なら build.sourcemap: true、webpack なら devtool: "source-map"dist/foo.js.map のような map ファイルが出力されているかをまず確認する。Node.js Debugging に sourcemap 関連設定の詳細がある。

3. launch.json で tsx / ts-node を attach 可能にする

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "tsx: index.ts",
      "runtimeArgs": ["--import", "tsx"],
      "program": "${workspaceFolder}/src/index.ts",
      "outFiles": ["${workspaceFolder}/**/*.{js,ts}"],
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}

TypeScript Debugging のとおり、outFiles を広めに取ると source への逆引きが安定する。runtimeArgs は Node の --import / --loader 仕様に従う(Node 20 以降は --import が推奨)。

4. 子プロセスにも attach する

node --inspect-brk=0 ./scripts/worker.js

--inspect-brk=0 を付けて起動し、Auto Attach を Always または Smart にしておくと、子プロセスや別ターミナルから起動した Node プロセスにも attach される。Always は全プロセスに attach、Smart--inspect 系フラグや package.json script から起動されたものだけが対象。

この記事は役立ちましたか?