VSCode Debug JS + TS Project February 26, 2025 In this post, I’ll briefly go over my VSCode setup for building and debugging a TypeScript project that includes JavaScript files. Before diving in, I’ll share some background and challenges of the project I’m working on. The project contains scattered legacy JavaScript code, but we are gradually migrating to TypeScript. My goal is to transpile both TypeScript and JavaScript files into a single dist folder while enabling debugging in VSCode using NVM (Node Version Manager) and launch.json. The setup (below) is straightforward - hope it helps if you’re dealing with a similar situation! tsconfig.json This will help transpile your project code into dist folder. You can name it differently, like build . {
"compilerOptions": {
"baseUrl": ".", // Specifies the base directory for resolving non-relative module names
"outDir": "dist", // Output directory for the compiled JavaScript files
"sourceMap": true, // Generate source maps for debugging
"allowJs": true, // Allow JavaScript files to be included in the project
"target": "es2015", // Compile to ES2015 (ES6) JavaScript code
"lib": ["ES2019"], // Include the ES2019 standard library for type checking
"moduleResolution": "node", // Resolve modules the same way Node.js does (e.g., using `node_modules`)
"skipLibCheck": true // Skip type checking of declaration files for faster compilation
},
"include": ["src/**/*.ts", "src/**/*.s", "index.js"], // Include TypeScript and JavaScript files in `src` and `index.js`
"exclude": ["node_modules"] // Exclude `node_modules` folder from the compilation
} .vscode/launch.json This defines a launch job for VSCode to use in Run and Debug . Here, I simply force NVM to use the default node version and run index.js in our dist folder. I also load my environment variables in .env.local . You can change it to the actual file with your env variables. {
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node-terminal",
"request": "launch",
"name": "Launch Server",
"preLaunchTask": "Build Server",
"sourceMaps": true,
"envFile": "${workspaceFolder}/.env.local",
"command": "nvm use default && node ${workspaceFolder}/dist/index.js"
}
]
} .vscode/tasks.json This defines a task that launch.json uses in preLaunchTask . This simply runs tsc command to build your project with your tsconfig.json file. {
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"options": {
"shell": {
"executable": "/bin/zsh",
"args": ["-l", "-i", "-c"]
}
},
"label": "Build Server",
"command": "nvm use default && npx tsc",
"problemMatcher": ["$tsc"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
} Another Way Another interesting way I also use is using concurrently , tsc --watch , and nodemon together. First, you run the command to run your server. You can use nodemon with its flag --inspect to expose the debugger port. This port will be used by VSCode to attach its debugger. concurrently --kill-others-on-fail "npx tsc --watch" "dotenv -e ./.env.local -- nodemon --inspect=9229 ./dist/index.js" Then, we use the launch config below to attach to our running process. {
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
// Command: concurrently --kill-others-on-fail "npx tsc --watch" "dotenv -e ./.env.local -- nodemon --inspect=9229 ./dist/index.js"
"type": "node",
"request": "attach",
"name": "Attach to Server",
"port": 9229,
"restart": true,
"sourceMaps": true
}
]
}
Read article >