DEV Community

Željko Šević
Željko Šević

Posted on • Originally published at sevic.dev on

Debugging Node.js apps with Visual Studio Code debugger

Rather than doing it with console logs, debugging with a debugger and breakpoints is recommended. VSCode provides a built-in debugger for JavaScript-based apps.

This post covers configuring and running a debugger for various Node.js apps in VSCode.

Configuration basics

VSCode configurations can use runtime executables like npm and ts-node. The executables mentioned above should be installed globally before running the configurations.

A configuration can use the program field to point to the binary executable package inside node_modules directory to avoid installing packages globally.

Runtime executables and programs can have arguments defined in runtimeArgs and args fields, respectively.

A configuration can have different requests:

  • attach - the debugger is attached to the running process
  • launch - the debugger launches a new process and wraps it

There are multiple configuration types:

  • node - runs the program from program field, and logs are shown in debug console
  • node-terminal - runs the command from command field and shows the logs in the terminal

The configuration file is .vscode/launch.json. The selected configuration on the Run and Debug tab is used as the default one.

Launch configs

Node

Below are examples of configurations for running Node processes with the debugger.

{
  "version": "0.2.0",
  "configurations": [
    // ...
    {
      "name": "Launch script in debug console",
      "program": "index.js", // update entry point
      "request": "launch",
      "type": "node",
      "skipFiles": [
        "<node_internals>/**"
      ]
    },
    {
      "name": "Launch script in the terminal",
      "command": "node index.js", // update entry point
      "request": "launch",
      "type": "node-terminal",
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Running npm scripts in debug mode

The debugger launches the following script in both configurations, dev in this case.

{
  "version": "0.2.0",
  "configurations": [
    // ...
    {
      "name": "Launch dev script in debug console",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "dev"
      ],
      "request": "launch",
      "type": "node",
      "skipFiles": [
        "<node_internals>/**"
      ]
    },
    {
      "name": "Launch dev script in the terminal",
      "command": "npm run dev",
      "request": "launch",
      "type": "node-terminal"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

ts-node

The following configurations will wrap the debugger around ts-node entry point.

{
  "version": "0.2.0",
  "configurations": [
    // ...
    {
      "name": "Launch ts-node script in debug console",
      "program": "node_modules/.bin/ts-node",
      "args": ["index.ts"], // update entry point
      "request": "launch",
      "type": "node",
      "skipFiles": [
        "<node_internals>/**"
      ]
    },
    {
      "name": "Launch ts-node script in the terminal",
      "command": "ts-node index.ts", // update entrypoint
      "request": "launch",
      "type": "node-terminal",
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

@babel/node

The following configuration will wrap the debugger around babel-node entry point.

{
  "version": "0.2.0",
  "configurations": [
    // ...
    {
      "name": "Launch babel-node script in debug console",
      "program": "node_modules/.bin/babel-node",
      "args": ["src"], // update entry point
      "request": "launch",
      "type": "node",
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Nodemon

Add new configuration with Run → Add configuration option, select Node.js: Nodemon Setup.

Update program field to point to the nodemon executable package, and add arguments with args field to point to the entry point.

{
  "version": "0.2.0",
  "configurations": [
    // ...
    {
      "name": "Launch nodemon script in debug console",
      "program": "node_modules/.bin/nodemon",
      "args": ["-r", "dotenv/config", "--exec", "babel-node", "src/index.js"], // update entry point
      "request": "launch",
      "type": "node",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "restart": true,
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Mocha

Add a new configuration, and choose Node.js: Mocha Tests configuration.

Replace tdd with bdd as u parameter and program field to point to the mocha executable package.

{
  "version": "0.2.0",
  "configurations": [
    // ...
    {
      "name": "Launch mocha tests",
      "program": "node_modules/.bin/mocha",
      "args": [
        "-u",
        "bdd",
        "--timeout",
        "999999",
        "--colors",
        "test"
      ],
      "request": "launch",
      "type": "node",
      "internalConsoleOptions": "openOnSessionStart",
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Attach configs

Auto Attach should be activated in settings with the With Flag value. In that case, auto-attaching is done when --inspect flag is given.

The debugger should be attached when some of the following scripts are executed.

{
  // ...
  "scripts": {
    // ...
    "start:debug": "node --inspect index.js", // update entry point
  }
}
Enter fullscreen mode Exit fullscreen mode
Jest
{
  // ...
  "scripts": {
    // ...
    "test:debug": "node --inspect -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
  }
}
Enter fullscreen mode Exit fullscreen mode
NestJS
{
  // ...
  "scripts": {
    // ...
    "start:debug": "nest start --debug --watch"
  }
}
Enter fullscreen mode Exit fullscreen mode

Debugging basics

During the debugging, the variables tab shows local variables. The step over option goes to the following statement in the codebase, while step into option goes deeper into the current statement.

Log points can add logs in debug console when a certain part of the codebase is executed without pausing the process.

Boilerplate

Here is the link to the boilerplate I use for the development.

Related reading

Latest comments (0)