Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debug Node.js Async/Await with Typescript+VSCode

I've checked the following answers:

async await with nodejs 7

How to debug async/await in visual studio code?

However neither have solved my issue.

I want to be able to debug native Async/Await from VSCode using Node.js v7.4.0 without the horrible Typescript transpiled version. I'm able to get Typescript to output the correct code ie no __awaiter etc. However, once I attempt to debug the code, all the transpiled state machine code appears!? So I can debug the code, its just not the code I want to debug. Is there anyway to prevent the debugged code from having the transpiled state machine code?

Here are the config files I have:

tsconfig.json

{
    "compilerOptions": {
        "target": "es2017",

        "module": "commonjs",
        "noImplicitAny": false,
        "sourceMap": true,
        "outDir": "lib",
        "noUnusedParameters": false,
        "noUnusedLocals": false,
        "skipLibCheck": true
        //"importHelpers": true
    },
        "exclude": [
        "node_modules"
    ]
}

launch.json

{
    "name": "Launch",
    "type": "node",
    "request": "launch",
    "program": "${workspaceRoot}/node_modules/jest-cli/bin/jest.js",
    "stopOnEntry": false,
    "cwd": "${workspaceRoot}",
    //"preLaunchTask": "tsc",
    "runtimeExecutable": null,
    "args": [
        "--runInBand"
    ],
    "runtimeArgs": [
        "--harmony-async-await",
        "--no-deprecation"
    ],
    "env": {
        "NODE_ENV": "development"
    },
    "console": "integratedTerminal",
    "sourceMaps": true,
    "outFiles": [
        "${workspaceRoot}/{lib}/**/*.js"
    ],
    "skipFiles": [
        "node_modules/**/*.js",
        "lib/**/*.js"
    ]
}

To further illustrate what I'm on about, here is a snippet of code in the outputted javascript:

let handler = subscription.messageSubscription.handler;
debugger;
await handler(message.message, context);

However when debugged it looks like this:

case 4:
    handler = subscription.messageSubscription.handler;
    debugger;
    return [4 /*yield*/, handler(message.message, context)];
case 5:
like image 387
dnp Avatar asked Jan 13 '17 23:01

dnp


2 Answers

I add "smartStep": true to launch.json and debugging the await/async pattern works as desired (using Node v8.4.0).

This is my launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceRoot}/src/main.ts",
      "cwd": "${workspaceRoot}",
      "console": "integratedTerminal",
      "outFiles": [ "${workspaceRoot}/dist/*.js" ],
      "sourceMaps": true,
      "preLaunchTask": "build",
      "smartStep": true
    }
  ]

}

For more details see https://code.visualstudio.com/updates/vApril#_smart-code-stepping.

It's not a perfect solution, because with smartStep you are not able to debug into library code, so you have manually to comment out this option if you want to debug into library. Maybe someone knows how to solve this minor inconvenience.

like image 99
Manfred Steiner Avatar answered Oct 27 '22 01:10

Manfred Steiner


Finally figured it out. Using Typescript and Jest. Sharing what I hav, hopefully it will help someone. Node 11, VScode 1.34.0

launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Jest Current File",
            "program": "${workspaceFolder}/node_modules/.bin/jest",
            "args": ["-i", "${relativeFile}"],                
            "console": "integratedTerminal",
            "internalConsoleOptions": "neverOpen",
            "disableOptimisticBPs": true,
            "sourceMaps": true,
            "smartStep": true,
            "windows": {
                "program": "${workspaceFolder}/node_modules/jest/bin/jest"
            }
        }
    ]
}


tsconfig.json:

{
    "compileOnSave": false,
    "compilerOptions": {
        "baseUrl": ".",
        "outDir": "./dist/out-tsc",
        "sourceMap": true,
        "inlineSources": true,
        "sourceRoot": "/",
        "declaration": false,
        "module": "es2015",
        "esModuleInterop": true,
        "resolveJsonModule": true,
        "stripInternal": true,
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es2017",
        "typeRoots": ["node_modules/@types"],
        "lib": ["es2018", "dom", "esnext.asynciterable"],
        "types": ["chrome", "node", "jest"]         
    }
}

However this works only in some scenarios. If you can compile you app to JS ES2017 that works. angular can't be compiled to that es version so. It works only with some test files. It is very frustrating that angular compile does not output es2017. and it wont for many years to come still.

like image 24
David Dehghan Avatar answered Oct 27 '22 00:10

David Dehghan