Configuring VSCode's Run and Debug for a TypeScript API in a nested npm workspace

I’m stuck trying to set up a launch.json config for my TypeScript Express API. The tricky part is it’s in an npm workspace that’s not in the project root.

My folder structure looks like this:

root/
├── resources/
├── monorepo/
│   ├── package.json
│   └── something/
│       └── myapi/
│           ├── package.json
│           ├── nodemon.json
│           └── src/
│               └── index.ts

In myapi/package.json, I have a script: “dev”: “nodemon src/index.ts”.

I’ve tried a few things in launch.json, like:

{
  "type": "node",
  "request": "launch",
  "name": "Debug myapi",
  "runtimeExecutable": "npm",
  "runtimeArgs": ["run", "dev", "--workspace", "myapi"],
  "cwd": "${workspaceFolder}/monorepo",
  "outputCapture": "std"
}

But I get errors about not finding the workspace.

Any ideas on how to make this work? I’m really lost and can’t seem to find any tutorials that address this exact setup.

hey jess, i’ve run into this before. try using the npm-workspace extension for vscode. it helps manage nested workspaces. then, update ur launch.json like this:

{
“type”: “node”,
“request”: “launch”,
“name”: “Debug myapi”,
“cwd”: “${workspaceFolder}/monorepo/something/myapi”,
“program”: “${workspaceFolder}/monorepo/something/myapi/src/index.ts”,
“outFiles”: [“${workspaceFolder}/monorepo/something/myapi/dist/**/*.js”]
}

this should work better for ur setup. lmk if u need more help!

Having worked with nested npm workspaces, I can relate to your frustration. One approach that’s proven effective is leveraging the ‘args’ property in your launch configuration. Try this:

{
  "type": "node",
  "request": "launch",
  "name": "Debug myapi",
  "cwd": "${workspaceFolder}/monorepo/something/myapi",
  "runtimeExecutable": "${workspaceFolder}/monorepo/node_modules/.bin/ts-node",
  "args": ["${workspaceFolder}/monorepo/something/myapi/src/index.ts"],
  "env": { "NODE_ENV": "development" },
  "sourceMaps": true,
  "outFiles": ["${workspaceFolder}/monorepo/something/myapi/dist/**/*.js"]
}

This configuration assumes you have ts-node installed in your monorepo. It directly executes your TypeScript file, bypassing npm scripts. Adjust the paths as necessary for your specific structure. Remember to install any required dependencies at the monorepo level for this to work smoothly.

I’ve dealt with a similar setup before, and it can be tricky. One approach that worked for me was to use the ‘program’ attribute instead of ‘runtimeExecutable’ in the launch configuration. Here’s what I’d suggest:

{
  "type": "node",
  "request": "launch",
  "name": "Debug myapi",
  "program": "${workspaceFolder}/monorepo/something/myapi/src/index.ts",
  "preLaunchTask": "tsc: build - monorepo/something/myapi/tsconfig.json",
  "outFiles": ["${workspaceFolder}/monorepo/something/myapi/dist/**/*.js"],
  "cwd": "${workspaceFolder}/monorepo/something/myapi",
  "env": { "NODE_ENV": "development" },
  "console": "integratedTerminal"
}

This configuration assumes you have a tsconfig.json in your myapi folder. The ‘preLaunchTask’ ensures TypeScript compilation before launching, and ‘outFiles’ helps with source map resolution. Adjust paths as needed for your specific structure. Also, make sure you have the required TypeScript compilation tasks set up in your tasks.json file.