【问题标题】:Visual Studio Code - Debug Node JS through TypeScriptVisual Studio Code - 通过 TypeScript 调试 Node JS
【发布时间】:2016-06-06 23:52:45
【问题描述】:

我目前正在尝试从 Visual Studio Code 调试一个用 TypeScript 编写的 Node JS 应用程序,但我遇到了一些问题。 我的情况类似于question

中描述的情况
|-- .settings
|----- launch.json
|-- bin
|----- app.js
|----- app.js.map
|--src
|----- app.ts
|-- tsconfig.json

然后我有 tsconfig.json 文件:

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

app.ts

console.log("Hello World!");

launch.json

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

然后我从命令行手动编译项目

tsc

所以我在 bin 目录中得到了两个文件。我在 app.ts 上设置了一个断点,最后使用 F5 运行解决方案,应用程序在正确的行开始和停止,但在 JS文件而不是 TS 一个:为什么???

我是在做错事还是试图实现不可能的目标?

非常感谢您的帮助! :)

编辑

我刚刚在GitHub 上分享了我的项目,以使事情变得更容易!可以的话就看看吧! :)

【问题讨论】:

    标签: node.js debugging typescript visual-studio-code


    【解决方案1】:

    绝对有可能。

    最可能的原因是node.js无法使用生成的map.js文件定位到对应的ts文件。 您可以尝试在 tsconfig.json 中指定“sourceRoot”以指向您项目的根目录:

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

    我个人更喜欢为此目的使用 gulp,在我的情况下,它看起来像这样(注意 - 我在这里不使用 node.js 全局变量 '__dirname' 来硬核 sourceRoot 路径):

    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"))]);
    });
    

    然后检查生成的 map.js 文件。它应该在开头包含类似这样的内容:

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

    最后:

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

    当它们组合在一起时,它们必须指向您的 app.ts 文件的有效位置。如果不是 - 相应地调整 sourceRoot。

    [编辑]

    以下是与您相同的项目部分(没有 gulp)——我可以在我的机器上调试。

    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/**"
        ]
    } 
    

    并在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"
    }
    

    [编辑]

    我已对您的 git 存储库进行了以下小更新,以便能够在本地对其进行调试。

    在根文件夹中添加 package.json,并指定 tsc 作为依赖项(我更喜欢本地安装):

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

    然后转到你的 git "stackoverflow" 根文件夹并在命令提示符下运行:

    npm install
    

    将 tasks.json 的“命令”行更改为:

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

    完成这些步骤并构建项目后,我能够在 app.ts 中放置一个断点,并且 VSCode 在运行时停止 (F5)

    [更新]

    tasks.json与windows兼容的版本:

    {
        "version": "0.1.0",
        "command": "tsc",
    
        "showOutput": "always",
    
        "windows": {
            "command": "node.exe"
        },
    
        "args": ["${workspaceRoot}\\node_modules\\typescript\\bin\\tsc.js"],
    
        "problemMatcher": "$tsc"    
    }
    

    希望这会有所帮助。

    【讨论】:

    • 我尝试了你的建议(没有 Gulp)但它不起作用,即使在地图文件中的路径是好的。您使用的是最新的代码版本(0.10.8)吗?
    • 是的——我愿意。我已经从 launch.json 中包含了我的配置部分,这对我来说非常适合。
    • 其实我的版本是0.10.9。很久以前我就在使用 VSCode/node.js - 所以我不认为它的版本相关。
    • 我已经添加了与你相同的测试项目的所有“部分”,没有使用 gulp。
    • 非常感谢!你解决了我的问题!我按照说明进行操作,在编译时出现以下错误:"c:\Users\brutus\Desktop\stackoverflow-master/node_modules/typescript/bin/tsc" not Recognized as an internal or external command 然后我将命令恢复为“tsc”,它运行良好,调试器也在正确的源文件中停止! :) 我很想检查 GitHub 上的原始版本,它也可以工作,没有 package.json 文件!我不知道为什么,也许我使用的是过时的 TypeScript 版本。非常感谢你,你很棒! :)
    【解决方案2】:

    这就是我调试 typescript (express) 项目的方式。使用 ts-node 你不必手动编译。使用这个配置我直接在我的打字稿文件中调试。希望这对某人有所帮助。

    {
      "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"
        }
      ]
    }
    

    【讨论】:

      【解决方案3】:

      在尝试弄清楚如何使用 aws Lambda 调试 TS+nodejs 时遇到了同样的问题。在 watch TS 文件更改方面,ts-node-dev 包似乎比 nodemon 快。

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

      最后在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"
            ]
          }
        ]
      }
          
      

      F5 应该使用本机httpexpress/koa/hapi... 等启动本地服务器。现在您可以在代码中设置断点。 ts-node-dev 还会在每次保存时观察 TS 文件更改和重新加载服务器。

      如果您碰巧使用aws lambda 进行开发,我为此包装了一个小型库

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

      【讨论】:

        猜你喜欢
        • 2021-09-12
        • 2016-12-29
        • 2021-05-25
        • 2017-12-18
        • 2015-12-18
        • 2018-05-19
        • 2015-08-30
        • 2016-11-28
        • 2016-07-29
        相关资源
        最近更新 更多