简体   繁体   中英

Visual Studio Code - Debug Node JS through TypeScript

I'm currently trying to debug a Node JS application written in TypeScript from Visual Studio Code but I have some issues. I have a situation similar to the one described on this question

|-- .settings
|----- launch.json
|-- bin
|----- app.js
|----- app.js.map
|--src
|----- app.ts
|-- tsconfig.json

Then I have the tsconfig.json file:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "outDir": "bin",
        "rootDir": "src",
        "sourceMap": true
    }
}

The app.ts :

console.log("Hello World!");

The launch.json :

{
    "version": "0.1.0",
    "configurations": [
        {
            "name": "Launch type",
            "type": "node",
            "program": "src/app.ts",
            "stopOnEntry": false,
            "sourceMaps": true,
            "outDir": "bin"
        }
    ]
}

Then I manually compile the project from the command line with

tsc

so I get two files in the bin directory. I set a breakpoint on app.ts and finally run the solution with F5 , the application starts and stops at the right line but on the JS file instead the TS one: why???

Am I doing something wrong or trying to achieve the impossible?

Thank you very much for your help! :)

EDIT

I've just shared my project on GitHub in order to make things easier! Take a look if you can! :)

It is absolutely possible.

The most likely reason is that the node.js cannot locate corresponding ts files using generated map.js file. You can try to specify "sourceRoot" in tsconfig.json to point to the root of your project:

sourceRoot: "/Users/SomeUser/projects/test"

Personally I prefer to use gulp for this purpose and in my case it would look like this (note - I do not hardcore sourceRoot path here by using node.js global variable '__dirname'):

var ts = require('gulp-typescript');

gulp.task('build.js.dev', function() 
{
    var tsProject = ts.createProject('tsconfig.json');

    var tsResult = tsProject.src()
        .pipe(sourcemaps.init())   
        .pipe(ts(tsProject));  

    return merge([
        //Write definitions 
        //tsResult.dts.pipe(gulp.dest("bin")),
        //Write compiled js
        tsResult.js.pipe(sourcemaps.write("./", { sourceRoot: __dirname })).pipe(gulp.dest("bin"))]);
});

After that examine the generated map.js file. It should contain something like this lines in the beginning:

"sources":["src/app.ts"]

and in the end:

"sourceRoot":"/Users/SomeUser/projects/test"

When combined together they must point to the valid location of your app.ts file. If not - adjust sourceRoot correspondingly.

[EDIT]

Below are the parts of the project identical to yours (without gulp) - that I can debug on my machine.

launch.json:

{
    // Name of configuration; appears in the launch configuration drop down menu.
    "name": "Launch Server",
    // Type of configuration.
    "type": "node",
    // Workspace relative or absolute path to the program.
    "program": "${workspaceRoot}/src/app.ts",
    // Automatically stop program after launch.
    "stopOnEntry": false,
    // 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": "${workspaceRoot}",
    // Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
    "runtimeExecutable": null,
    // Optional arguments passed to the runtime executable.
    "runtimeArgs": ["--nolazy"],
    // Environment variables passed to the program.
    "env": {
        "NODE_ENV": "development"
    },
    // Use JavaScript source maps (if they exist).
    "sourceMaps": true,
    // If JavaScript source maps are enabled, the generated code is expected in this directory.
    "outDir": "${workspaceRoot}/bin",
    "request": "launch"
}

tsconfig.json:

{ 
    "compilerOptions": { 
        "emitDecoratorMetadata": true, 
        "experimentalDecorators": true,
        "moduleResolution": "node",
        "module": "commonjs", 
        "target": "es6",
        "sourceMap": true,
        "outDir": "bin",
        "declaration": true,
        "noImplicitAny": true
    },
    "exclude": [
        "node_modules",
        "bin",
        ".vscode",
        "typings/browser.d.ts",
        "typings/browser/**"
    ]
} 

And build task in tasks.json:

{
    "version": "0.1.0",

    // The command is tsc. Assumes that tsc has been installed locally using npm install typescript
    "command": "${workspaceRoot}/node_modules/typescript/bin/tsc",

    // The command is a shell script
    "isShellCommand": true,

    // Show the output window only if unrecognized errors occur.
    "showOutput": "silent",

    // args is the HelloWorld program to compile.
    "args": [],

    // use the standard tsc problem matcher to find compile problems
    // in the output.
    "problemMatcher": "$tsc"
}

[EDIT]

I have done the following minor updates to your git repository to be able to debug it locally.

Add package.json in the root folder, and specify there tsc as dependency (I prefer local installations):

{
  "name": "123",
  "namelower": "123",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
  },
  "devDependencies": {
    "typescript": "latest"
  }
}

then go to your git "stackoverflow" root folder and run in command prompt:

npm install

Change in tasks.json "command" line to:

"command": "${workspaceRoot}/node_modules/typescript/bin/tsc",

After doing these steps and building the project I was able to put a breakpoint in app.ts and VSCode stopped on it upon run (F5)

[UPDATE]

Version of tasks.json compatible with windows:

{
    "version": "0.1.0",
    "command": "tsc",

    "showOutput": "always",

    "windows": {
        "command": "node.exe"
    },

    "args": ["${workspaceRoot}\\node_modules\\typescript\\bin\\tsc.js"],

    "problemMatcher": "$tsc"    
}

Hope this helps.

Juli 2022 Nothing additional (like gulp etc.) is necessary

Step 1:

Simply install ts-node globally:

npm i -g ts-node

Step 2:

Add a new configuration in launch.json (VSCode). The following is for macOS; for other operating systems, modify the runtimeExecutable property accordingly:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "TypeScript Debugging",
      "type": "node",
      "request": "launch",
      "args": ["${relativeFile}"],
      "cwd": "${workspaceRoot}",
      "runtimeExecutable": "/opt/homebrew/bin/ts-node"
    }
  ]
}

Step 3:

Open the TypeScript file you want to debug and set a break point.

Step 4:

and click left on "Rund and Debug."

VSCode 中的 TypeScript 调试

Backup: tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "lib": ["ESNext", "DOM"],
    "module": "esnext",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipDefaultLibCheck": true,
    "skipLibCheck": true,
    "sourceMap": true
  }
}

This is how I am debugging my typescript (express) project. Use ts-node you don't have to compile manually . Using this configs i am directly debugging in my typescript files. Hope this helps someone.

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Current TS File",
      "type": "node",
      "request": "launch",
      "args": ["${workspaceRoot}/src/app.ts"],
      "runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
      "sourceMaps": true,
      "cwd": "${workspaceRoot}",
      "protocol": "inspector"
    }
  ]
}

was having the same issue trying to figure out how to debug TS+nodejs with aws Lambda. Looks like the ts-node-dev package is faster than nodemon in terms of watch TS file changes.

npm install ts-node-dev --save-dev

finally add below config in launch.json :

{
  "version": "1.0.0",
  "configurations": [
    {
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "name": "Local Server",
      "restart": true,
      "request": "launch",
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/ts-node-dev",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "type": "node",
      "runtimeArgs": [
        "--respawn"
      ],
      "args": [
        "${workspaceFolder}/src/script/local.server.ts"
      ]
    }
  ]
}
    

Press F5 should launch your local server either with native http or express/koa/hapi... etc. Now you can set break points in code. Also the ts-node-dev will watch the TS file change and reload server on each save.

I wrapped up a small library for this if you happen to develop with aws lambda

https://github.com/vcfvct/ts-lambda-local-dev

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM