Debug Javascript/TypeScript
JavaScript/TypeScript Debugging
Node.js 6.3 introduced the “inspect” and “inspect-brk” CLI arguments that make node to listen via WebSockets for diagnostic commands as defined by the Chrome Debugging Protocol.
Additionally, the Node CLI also provides a “require” argument meant to preload modules (node –require [file]), but most importantly, for debugging purposes, it allows 3rd party libraries to hook into the “require.extensions” module and make Node able to compile and generate source-maps for other languages like TypeScript. For debugging TypeScript we’ll use ts-node. It’s important to remember that in your tsconfig.file , that can be generated by running tsc –init , you should have “sourceMap”: true , which is the default value.
When a Node.js app is started in “inspect” mode, 2 important things will happen:
- An UUID will be assigned to this debugging session and a WebSockets end-point will spin up at ws://127.0.0.1:9229/[UUID] . This end-point will stream real-time events with the current state of the running code.
- An HTTP end-point will spin up at http://127.0.0.1:9229/json . This allows agents like the Chrome DevTools to know about every running Node session and their respectiveUUID .
With Chrome DevTools for JavaScript
To start application in debug mode:
node --inspect app.js
node --inspect-brk=9229 app.js
- set debug port to 9229 and add a breakpoint at the first line
A Node.js process started without –inspect can also be instructed to start listening for debugging messages:
node -e 'process._debugProcess(30464)'
- to attach debugger to a running application(not in inspect mode)kill -SIGUSR1 30464
Debug in Chrome:
chrome://inspect
about:inspect
Cmd + P
to navigate to desired file
With Chrome DevTools for TypeScript
Start application with node --inspect --require ts-node/register index.ts
and it is the same after that.
With VSC for JavaScript
Just by selecting the target JavaScript file, clicking on the Debug tab (Shift + Cmd + D on Mac) and hitting the ▶️ button should be enough to start debugging the current JavaScript file even without selecting any launch configuration. VS Code will automatically start Node with the –inspect parameter and attach to it.
You can also very easily create a launch configuration for attaching to a Node process running from the terminal.1
2
3
4
5
6
7
8
9
10{
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach",
"port": 9229
}
]
}
After the configuration is in place, start the application in inspection mode from the terminal.
With VSC for TypeScript
VS Code, when using a configuration “type”:”node” will not allow the program to be a .ts file (at least as this article is being written), then you’re left with 2 options: You can either run ts-node passing a .ts file as the argument (${relativeFile} returns the currently focused one):
1 | { |
or you can specify the runtimeExecutable to be NPM (instead of the default: node) and pass a script name as an argument. Both of them have the exact same effect:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch via NPM",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run-script",
"start:debug:ts"
],
"port": 9229
},
]
}
alternatively this one should work too:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch current file w/ ts-node",
"protocol": "inspector",
"args": ["${relativeFile}"],
"cwd": "${workspaceRoot}",
"runtimeArgs": ["-r", "ts-node/register"],
"internalConsoleOptions": "openOnSessionStart"
}
]
}
If you want, instead, to attach to a running TypeScript process spawn from a terminal, it is the exact same script we used for pure JavaScript.
Debug Vue.js application with VSC and Chrome
Debug Jest test cases with VSC and Chrome
A working example of VSC launch.json:
1 | { |
Another working example with ENV variables:
1 | { |