Node.js with TypeScript, Debug inside VSCode and Nodemon
Tags: node, typescript, javascript, vscode
Published: 2019-03-23 05:50:25

Setup Node.js and TypeScript can be straightforward. Our daily work sometimes involves a lot of debugging and we also need to reload our server. 

Let's walk through how we can setup Node.js with TypeScript + Nodemon + Debug inside VSCode (as an extra, you can debug it inside Chrome DevTools).

Less talk, more code! 🤓

# 📦 Dependencies and Configurations

```bash
$ mkdir devto-node-typescript
$ cd $_
```

Adding our dependencies:

```bash
$ yarn init -y
$ yarn add @types/express@^4.16.1 express@^4.16.4 nodemon@^1.18.10 ts-node@^8.0.3 typescript@^3.3.4000
```

Here is our dependencies list:

- `@types/express@^4.16.1`
- `express@^4.16.4` 
- `nodemon@^1.18.10`
- `ts-node@^8.0.3`
- `typescript@^3.3.4000`

Now, let's create our `nodemon.json` file:

```bash
$ touch nodemon.json
$ vim $_
```

And paste the following:

```js
{
  "restartable": "rs",
  "ignore": [".git", "node_modules/**/node_modules"],
  "verbose": true,
  "execMap": { // [A]
    "ts": "node --require ts-node/register"
  },
  "watch": ["src/"],
  "env": {
    "NODE_ENV": "development"
  },
  "ext": "js,json,ts"
}
```

- **// [A]**: Here we're saying to nodemon: "Hey nodemon, if we run "nodemon" with a ".ts" file, please, use this line to execute the file". Because of that, now we can do `nodemon server.ts` and it will use `ts-node` to compile our file.

To learn more about Nodemon config, you can check the [sample in their repository](https://github.com/remy/nodemon/blob/master/doc/sample-nodemon.md)

Now, let's create our `tsconfig.json` file:

```
$ touch tsconfig.json
$ vim $_
```

And use:

```js
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "./dist",

    "strict": true,

    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,

    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.test.ts"]
}
```

There's no much difference from the default config (e.g. when you run `tsc --init`)

We are almost there, let's create a **npm script** to start our future server:

```js
// ...

"scripts": {
  "dev": "nodemon src/entry.ts"
}

// ...
```

Now, it's time to create our server.

# 💻 Writing our server and some routes

As we saw in our nodemon and npm scripts configuration, we need to create a folder called `src` and file called `entry.ts`:

```bash
$ mkdir src
$ cd $_
$ touch entry.ts
$ vim $_
```

Let's write the following:

```js
import express from 'express';

const server = express();

server.use('/_healthcheck', (_req, res) => {
  res.status(200).json({ uptime: process.uptime() });
});

server.listen(4004, () => { console.log('Running at localhost:4004') })
```

Now we can run:

```bash
$ yarn dev
```

And see our Node.js with TypeScript + Nodemon server running:

![](https://thepracticaldev.s3.amazonaws.com/i/rgy8804esrcxbwznnsvt.png)

Fantastic! 🎉

But wait... one important part is missing, how I can debug this thing? 😱

# 📊 Attaching Debug configuration to our project

Using [**nodemon** we simply pass the `--inspect`](https://github.com/remy/nodemon#usage) flag to make our Node process debuggable. Let's create a new npm script for that:

```js
// ...

"scripts": {
  // ...
  "dev:debug": "nodemon --inspect src/entry.ts"
}

// ...
```

If we run:

```bash
$ yarn dev:debug
```

We can see the debug option in our logs:

![](https://thepracticaldev.s3.amazonaws.com/i/86eiaokpflbmxavqo8r8.png)

Great! Let's create our VSCode configuration:

```
$ mkdir .vscode
$ cd $_
$ touch launch.json
$ vim $_
```

And paste the following:

```js
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Node: Nodemon",
      "processId": "${command:PickProcess}",
      "restart": true,
      "protocol": "inspector"
    }
  ]
}
```

This configuration is based in one of [Microsoft Recipes](https://github.com/Microsoft/vscode-recipes) for VSCode.

Let's open our VSCode editor and do go the "Debug" panel:

![](https://thepracticaldev.s3.amazonaws.com/i/fdeotq5l6xc7pelu4u1r.png)

With our `yarn dev:debug` running, let's press the green arrow shown in the screenshot above.

First, we need to select the process pointing to our server:

![](https://thepracticaldev.s3.amazonaws.com/i/ccc394dcbg73e7e2yhes.png)

After we select it, we can see a floating debug panel and some UI changes:

![](https://thepracticaldev.s3.amazonaws.com/i/cghe1q7ks62tje7ggxh0.png)

Now you can add a breakpoint in your code and have fun inside your editor with server reload by nodemon:

![](https://thepracticaldev.s3.amazonaws.com/i/dcqxhq5picmz2mi11h6n.png)

Delightful experience! ❤️ 🎉 😎

# 🌐 Extra: It also works in Google Chrome DevTools

Yep. We can use the following steps:

- Navigate to `chrome://inspect`

![](https://thepracticaldev.s3.amazonaws.com/i/vioxqtiy503xt9ei0azh.png)

- Click `inspect` inside **Remote Target** section pointing to your server and have fund debugging your server using Chrome DevTools:

![](https://thepracticaldev.s3.amazonaws.com/i/ae91yd4ge93bxwfe64fb.png)

**NOTE:** I tried to use **"Open dedicated DevTools for Node"** option, but it doesn't work well :( If you know how to make it work, share with us!

# ☕️ I want it all and more!

What about tests? Folder structure? There's a default project?

Say no more! For my personal use, I've a small non-opinionated default project in:

https://github.com/oieduardorabelo/node-typescript

You will find:

- Node.js + TypeScript
- Jest
- Nodemon

Feel free to fork, contribute and use! 

Happy coding! 🙌