how to debug typescript files in visual studio code

TypescriptVisual Studio-Code

Typescript Problem Overview


using version 0.3 of visual studio code and I'm not sure how to enable sourcemaps and debug the ts file

I get the following error can't launch program '/Projects/app-server/server.ts'; enabling source maps might help

how do I enable sourcemaps and typescript debugging. Sourcemap is set to true in my

tsconfig.json

{
	"compilerOptions": {
		"target": "ES5",
		"module": "commonjs",
		"sourceMap": true
	}
}

launch.json

{
	"version": "0.1.0",
	// List of configurations. Add new configurations or edit existing ones.  
	// ONLY "node" and "mono" are supported, change "type" to switch.
	"configurations": [
		{
			// Name of configuration; appears in the launch configuration drop down menu.
			"name": "Launch server.ts",
			// Type of configuration. Possible values: "node", "mono".
			"type": "node",
			// Workspace relative or absolute path to the program.
			"program": "server.ts",
			// Automatically stop program after launch.
			"stopOnEntry": true,
			// Command line arguments passed to the program.
			"args": [],
			// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
			"cwd": ".",
			// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
			"runtimeExecutable": null,
			// Environment variables passed to the program.
			"env": { }
		}, 
		{
			"name": "Attach",
			"type": "node",
			// TCP/IP address. Default is "localhost".
			"address": "localhost",
			// Port to attach to.
			"port": 5858
		}
	]
}

Typescript Solutions


Solution 1 - Typescript

I think it got simpler and simpler over the releases...

I have installed ts-node (https://github.com/TypeStrong/ts-node), so my config files end up very simple.

Install ts-node with npm install ts-node --save-dev in the project folder - thanks to Hrafnkell in the comments

launch.json
{
        "name": "Launch index.ts",
        "type": "node",
        "request": "launch",
        "runtimeArgs": [
            "-r",
            "ts-node/register"
        ],
        "args": [
            "${workspaceFolder}/src/index.ts"
        ]
}

There are two things worth noting:

  • runtimeArgs - passed to node to register the ts-node to handle the TypeScript files.
  • there is no program property. The name of TS file to start is given as first argument instead.

That way you do not need to compile the TS to JS, you can even have modules written in TS not compiled to JS yet.

Solution 2 - Typescript

This configuration is working fine for me:

Project distribution
|-- .vscode
    |----- launch.json
|-- bin
    |----- app.js
    |----- app.js.map
|-- src
    |----- app.ts
|-- node_modules
    |-- [..]
|-- tsconfig.json
|-- [...]

The idea is compile the typescript under src folder and place it under bin folder.

tsconfig.json

It's important to active sourceMap option.

{
    "compilerOptions": {
        "emitDecoratorMetadata": true,
        "module": "commonjs",
        "target": "ES5",
        "outDir": "bin",
        "rootDir": "src",
        "sourceMap": true
    }
}
launch.json

==== EDIT ====

This is the configuration I'm currently using at Visual Studio Code v1:

{
    "version": "0.2.0",
    "configurations": [
        {
            "args": [],
            "cwd": "${workspaceRoot}",
            "env": {
                "NODE_ENV": "development"
            },
            "externalConsole": false,
            "name": "DEBUG",
            "outDir": "${workspaceRoot}/bin",
            "preLaunchTask": "compile",
            "program": "${workspaceRoot}/src/app.ts",
            "request": "launch",
            "runtimeArgs": [
                "--nolazy"
            ],
            "runtimeExecutable": null,
            "sourceMaps": true,
            "stopOnEntry": false,
            "type": "node"
        },
        {
            "name": "Attach",
            "type": "node",
            "request": "attach",
            "port": 5858
        }
    ]
}

Note the key preLaunchTask is extremely helpful if you're using any task runner as gulp because the IDE is able to detect its tasks by name.

Running
  1. Compile your ts (typing in a terminal rm -r bin/ ; tsc or executing your compiling task)
  2. In visual Code play Launch type (our configuration name)
  3. Enjoy!

debuging

Solution 3 - Typescript

This is what has been working for me with latest TS and VsCode as of November,2017

Following configuration will help you start the server and debug TS inside VS Code

This is what my tsconfig.json looks like:

{
    "compilerOptions": {
        "declaration": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "lib": ["es2017", "dom"],
        "module": "commonjs",
        "moduleResolution": "node",
        "outDir": "../build",
        "sourceMap": true,
        "target": "es2016",
        "typeRoots": [
            "../node_modules/@types"
        ]
    },
    "include": [
        "**/*.ts"
    ],
    "exclude": [
        "../node_modules",
        "../*.js"
    ]
}

And this is what my directory structure looks like:

enter image description here

If you pay attention you would see my src folder and build folder(containing resultant transpiled JS and map files) lives side by side which really helps me maintain a logical directory structure.

Ok, now comes the launch config:

{
            "type": "node",
            "request": "launch",
            "name": "Start and Debug",
            "preLaunchTask": "nb-tsc-watch",
            "timeout": 10000,
            "program": "${workspaceFolder}/backend/src/app.ts",
            "restart": true,
            "cwd": "${workspaceRoot}",
            "outFiles": [
                "${workspaceFolder}/backend//build/**/*.js"
            ],
            "sourceMaps": true
        }

You can use whatever preLaunchTask you want to use, or even skip it. If you skip it, you would have to transpile TS to JS manually.

This is what I do in my task nb-tsc-watch

{
            "label": "nb-tsc-watch",
            "type": "typescript",
            "tsconfig": "backend/src/tsconfig.json",
            "option": "watch",
            "problemMatcher": [
                "$tsc-watch"
            ]
        }

Solution 4 - Typescript

For the more later version of VSCode as of Feb/2017, this is what worked for me (it's a combination of what both @manu and @tommy Falgout have provide):

It assumes that your json out files are in a dest folder and your source in a src folder, respectively

/.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [{
            "type": "node",
            "request": "launch",
            "name": "Launch",
            "sourceMaps": true,
            "stopOnEntry": true,
            "console": "internalConsole",
            "cwd": "${workspaceRoot}",
            "program": "${workspaceRoot}/src/main.ts",
            "outFiles": ["${workspaceRoot}/dest/*.js"]
        },
        {
            "type": "node",
            "request": "attach",
            "name": "Attach to Process",
            "port": 5858,
            "outFiles": []
        }
    ]
}

tsconfig.json

{
    "compilerOptions": {
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true,
        "module": "commonjs",
        "outDir": "dest",
        "rootDir": "src"
    },
    "exclude": [
        "node_modules"
    ]
}

Solution 5 - Typescript

The below setup tests mocha chai with breakpoints. It works by transpiling src to lib directory and then running tests in lib with sourceMapping back to src.

.vscode/launch.json

{
    "type": "node",
    "request": "launch",
    "preLaunchTask": "tsc",
    "name": "Run Mocha",
    "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
    "args": ["lib/**/*.js"],
    "cwd": "${workspaceRoot}",
    "sourceMaps": true,
    "outFiles": ["${workspaceRoot}/lib/**/*.js"]
}

tsconfig.json

{
  "compilerOptions": {
      "module": "commonjs",
      "sourceMap": true,
      "outDir": "lib",
      "target": "es6"
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

.vscode/tasks.json

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "tsc",
    "isShellCommand": true,
    "args": ["-p", "."],
    "showOutput": "silent",
    "problemMatcher": "$tsc"
}

package.json to show installed modules. Scripts are irrelevant to debugging.

"scripts": {
  "test": "mocha --compilers ts:ts-node/register src/**/*.spec.ts",
  "test:coverage": "nyc -e '.ts' npm test"
},
"dependencies": {
  "@types/chai": "^3.4.35",
  "@types/mocha": "^2.2.39",
  "@types/node": "^7.0.5",
  "@types/sinon": "^1.16.35",
  "chai": "^3.5.0",
  "mocha": "^3.2.0",
  "nyc": "^10.1.2",
  "sinon": "^1.17.7",
  "ts-node": "^2.1.0",
  "typescript": "^2.2.1"
}
  • Mac OSX 10.12.3 Sierra
  • Visual Studio Code 1.10.1
  • NodeJS v7.7.1

Solution 6 - Typescript

The answer by @manu pointed me in the right direction; however, with the latest version of VSCode, I still had the same problem. This is the fix that worked for me:

https://github.com/Microsoft/vscode/issues/13499

"outFiles": [ "${workspaceRoot}/js/*.js" ]

Solution 7 - Typescript

2017/12/17
.vscode/launch.json


    {
      // 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",
          "request": "launch",
          "program": "${workspaceRoot}/src/index.ts",
          "outFiles": [
            "${workspaceRoot}/dist/index.js"
          ],
          "sourceMaps": true,
          "stopOnEntry": false,
          "args": [],
          "cwd": "${workspaceRoot}",
          "env": {
              "NODE_ENV": "development"
          },
          "console": "internalConsole",
          "preLaunchTask": "compile",
          "name": "DEBUG"
        },
        {
          "type": "node",
          "request": "attach",
          "name": "Attach to Process",
          "port": 5858
        }
      ]
    }

*.vscode/tasks.json*

    {
      // See https://go.microsoft.com/fwlink/?LinkId=733558
      // for the documentation about the tasks.json format
      "version": "2.0.0",
      "tasks": [
        {
          "label": "compile",
          "type": "typescript",
          "tsconfig": "tsconfig.json",
          "problemMatcher": [
              "$tsc"
          ],
          "group": {
              "kind": "build",
              "isDefault": true
          }
        }
      ]
    }

*tsconfig.json*

    {
      "compilerOptions": {
        "declaration": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "moduleResolution": "node",
        "target": "es5",
        "module": "commonjs",
        "sourceMap": true,
        "outDir": "dist",
        "rootDir": "src"
      },
      "include": [
        "**/*.ts"
      ],
      "exclude": [
        "node_modules"
      ]
    }

Solution 8 - Typescript

If you do not want to hardcode filenames but like simple Grogi's version here ? Using info from VS variable reference page you can do 2 things:

npm i ts-node

then launch.json like (full in case, but you can grab only this one configurations from):

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch TS",
            "type": "node",
            "request": "launch",
            "runtimeArgs": [
                "-r",
                "ts-node/register"
            ],
            "args": [
                "${workspaceFolder}/${fileBasename}"
            ]
        }
    ]
}

Few examples from that VSC page - sometimes somewhere you can use Ctrl+Space to get them, but does not work inside existing for me:

${workspaceFolder} - /home/your-username/your-project
${workspaceFolderBasename} - your-project
${file} - /home/your-username/your-project/folder/file.ext
${relativeFile} - folder/file.ext
${relativeFileDirname} - folder
${fileBasename} - file.ext
${fileBasenameNoExtension} - file
${fileDirname} - /home/your-username/your-project/folder
${fileExtname} - .ext
${lineNumber} - line number of the cursor
${selectedText} - text selected in your code editor
${execPath} - location of Code.exe

Solution 9 - Typescript

Auto-configuration approaches

A simple, automatic config is sufficient for many use cases - no need to configure launch.json manually. Prerequisite: Enable sourcemaps in workspace tsconfig.json:

{
  "compilerOptions": {
    "sourceMap": true,
    // ...
  }
}
1.) Debug current file without launch.json

Just open or re-focus the file and then press F5 (Start Debugging). If multiple debug environments exist like Chrome and Node.js, select the latter.

Note: This currently requires no other entry to be present in launch.json. Next VS Code release will come with single file debug improvements.

2.) Auto Create launch.json

Go to Debug view (CtrlShiftD) and click "create a launch.json file". This will create a debug entry for the main field file of package.json or the active file, if no main exists. Example:

  "configurations": [ // auto-generated 
    { 
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "program": "${workspaceFolder}\\dist\\A.js",
      "preLaunchTask": "tsc: build - tsconfig.json",
      "outFiles": [
        "${workspaceFolder}/dist/**/*.js"
      ]
    }
  ]

Note: This requires launch.json to not be present before.

3.) Attach debugger to running program

Turn on Auto Attach feature in settings.json or via UI → "Debug: Toggle Auto Attach".

"debug.node.autoAttach": "on" // in settings.json

Start the node program in debug mode. Shortly after, VS Code will start debugging.

node --inspect-brk dist/A.js

Or use "Debug: Attach to Node Process" (also with launch.json: "${command:PickProcess}").

Solution 10 - Typescript

I just wrote my own PowerShell function as preLaunchTask. This can be a worse solution than previous ones, but can add more flexibility to inject more task under preLaunchTask field. Because currently it does not support array, and allows only one task to be run before launch action.

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Node.js",
            "program": "${file}",
            "preLaunchTask": "RebuildTypeScript",
            "outFiles": [
                "${workspaceRoot}/js/**/*.js"
            ]
        }
    ]
}

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "typescript",
            "tsconfig": "tsconfig.json",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },        
        {
            "taskName": "RebuildTypeScript",
            "type": "shell",
            "command": "Powershell ./RebuildTypeScript.ps1",
            "group": "none",
            "presentation": {
                "reveal": "never"
            }
        }       
    ]
}

RebuildTypeScript.ps1

$currentDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
function CompileTypeScriptFiles($folder) {
    $tsFiles = Get-ChildItem $folder -Filter "*.ts" -Recurse
    $tsFiles | ForEach-Object {
        $tsFile = $_.FullName;
        $options = $tsFile + " --outDir js --sourceMap"
        Start-Process "tsc" $options 
    }
}


CompileTypeScriptFiles $currentDir

Solution 11 - Typescript

For me, after so many launch.json configs. I came to find that using jestJs with istanbul cause my breakpoint not to break at the correct location until I set the config to:

config.collectCoverage = false;

See issue

Solution 12 - Typescript

If you are running your script from a command line, in the latest Visual Studio Code versions you can skip the creation of launch.json which is sometimes a laborous task. Instead, you can automatically attach the debugger to the any ts-node or node command you run from the command line.

  1. Enable source maps for your tsconfig.json - TypeScript config needs source map support or debugging is not possible.
{
  "compilerOptions": {
    "sourceMap": true
  },
}
  1. Enable Auto Attach on Visual Studio Code debugger. It is a button on the task bar, but can be also accessed through the command palette.

auto attach

  1. Instead of launching the script as:
ts-node myscript.ts

Launch it as

node -r ts-node/register --inspect-brk myscript.ts

You will see this on Node startup:

Debugger listening on ws://127.0.0.1:9229/8bb6dcc8-a73c-405e-b1fe-69a3d7789a20
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.

Then Visual Studio Code debugger will

  1. Stop on the first line of the program

  2. Stop on any of the following breakpoints set in the Visual Studio Code editor

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMonkeyBonkeyView Question on Stackoverflow
Solution 1 - TypescriptGrogiView Answer on Stackoverflow
Solution 2 - TypescriptManu ArteroView Answer on Stackoverflow
Solution 3 - TypescriptAakash MalhotraView Answer on Stackoverflow
Solution 4 - Typescriptcode5View Answer on Stackoverflow
Solution 5 - TypescriptmummybotView Answer on Stackoverflow
Solution 6 - TypescriptTommy FalgoutView Answer on Stackoverflow
Solution 7 - TypescriptBruce LeeView Answer on Stackoverflow
Solution 8 - TypescriptTomView Answer on Stackoverflow
Solution 9 - Typescriptford04View Answer on Stackoverflow
Solution 10 - TypescriptTeoman shipahiView Answer on Stackoverflow
Solution 11 - TypescriptfredtmaView Answer on Stackoverflow
Solution 12 - TypescriptMikko OhtamaaView Answer on Stackoverflow