Reputation: 6265
I have a JS web app that has a client and server bundle, both built using webpack's node api.
Running my project in dev mode goes through these steps:
I want to add node server debugging using vscode.
So far, I've added the following flags during step 3, when I launch a new child process.
['--inspect=9222', '--no-lazy', '--inspect-brk']
My launch.json file in vscode looks like this
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to dev server",
"type": "node",
"request": "attach",
"protocol": "inspector",
"address": "localhost",
"port": 9222,
"restart": true,
"trace": true,
"stopOnEntry": true
}
]
}
When I start the server and run the debugger, things mostly work.
However, I'd love to fix the following two things:
"stopOnEntry": true
, the debugger will not pick up any breakpoints, unless I include "--inspect-brk"
when launching my child process. This is annoying, because if I'm not running the debugger, the process will hang and will not continue execution. With this flag included, when I run the debugger, the built dist/server/index.js
file will open in my editor with a breakpoint on line 1. If I hit continue, all future debugging works.E.g. _myFunction.default instead of myFunction
. Does vscode have a way to correctly map the built .js file to the pre-built source code in my project? I saw the remoteRoot
and localRoot
options, but could not get them to work (and am unsure if these are the correct options).Thanks!
Upvotes: 5
Views: 4010
Reputation: 74740
With the new JavaScript debugger in VS Code 1.47 and later versions, child processes are automatically debugged in Node.js - just set breakpoints where needed.
Examplelaunch.json
(with TypeScript source to illustrate the sourcemap approach):
{
"type": "pwa-node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/main.ts", // use .ts source
"outFiles": ["${workspaceFolder}/dist/**/*.js"], // search here for sourcemaps
}
Example main.ts
:
const { spawn } = require("child_process");
const args = [path.resolve("./child.js")];
const proc = spawn(process.execPath, args, { stdio: "inherit" });
See this post for an explanation of pwa-node
.
program
: specifies main source file to be debugged. You can directly reference the .ts
source file - VS Code will search the workspace for sourcemaps or consult outFiles
.
outFiles
: tell VS Code to explicitely search for sourcemaps in these glob locations.
sourceMaps
: if VS code shall look for sourcemaps; defaults to true
, so no need to set.
stopOnEntry
: breaks immediately when program launches - same, as a breakpoint on first line. 1
nolazy
: ensures that breakpoints are validated before the code is run and don't "jump". Per default, VS Code sets this flag automatically, so it can be left out.
remoteRoot
/ localRoot
: are for remote debugging and are not directly related to generating sourcemaps (see OP question).
autoAttachChildProcesses
: was used to automatically attach to child processed launched in debug mode; no need to set it with new debugger.
--inspect
: starts the program in debug mode without waiting for the debugger to be attached.
--inspect-brk
: same as --inspect
, but waits for the debugger to attach before starting.
You can set one of these to enable debug mode for a program started on the command-line. Note: VS Code now can also auto-attach from integrated terminal without these flags given.
For webpack, you can generate sourcemaps with inline-source-map
or source-map
2.
// inside webpack.config.js
devtool: "inline-source-map",
If babel-loader
is used, sourcemaps should be considered and merged automatically by webpack with above config entry. For TypeScript, see the Webpack docs.
If that does not work in older versions, pass a conditional DEBUG
environmental variable for --inspect
/--inspect-brk
together with autoAttachChildProcesses
:
const runner = spawn(process.execPath,
[...(process.env.DEBUG === "true" ? ["--inspect-brk"] : []), ...args],
);
// inside launch.json configuration
"env": {
"DEBUG": "true"
},
1 Despite this developer comment, stopOnEnty
has not been propagated to child processes for me - even with autoAttachChildProcesses
and child processed started with --inspect
.
2 These options provide best compatibility from my experience.
Upvotes: 3