使用 babel-node 在 Visual Studio 代码中调试

debugging in Visual Studio Code with babel-node

我正在使用:

我无法使用以下启动文件在断点处停止。 调试器 运行s 并附加到一个端口,但是当我 运行 带有断点的应用程序时,它不会在断点处停止并且 运行s 直接通过。 有哪位弄过这个的,请指教。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch",
            "type": "node",
            "request": "launch",
            "program": "${workspaceRoot}/src/app.js",
            "stopOnEntry": false,
            "args": [],
            "cwd": "${workspaceRoot}",
            "preLaunchTask": null,
            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/babel-node.cmd",
            "runtimeArgs": [
                "--nolazy"
            ],
            "env": {
                "NODE_ENV": "development"
            },
            "externalConsole": false,
            "sourceMaps": false,
            "outDir": null
        },
        {
            "name": "Attach",
            "type": "node",
            "request": "attach",
            "port": 5858,
            "address": "localhost",
            "restart": false,
            "sourceMaps": false,
            "outDir": null,
            "localRoot": "${workspaceRoot}",
            "remoteRoot": null
        },
        {
            "name": "Attach to Process",
            "type": "node",
            "request": "attach",
            "processId": "${command.PickProcess}",
            "port": 5858,
            "sourceMaps": false,
            "outDir": null
        }
    ]
}

我能够按照以下步骤让它工作:

Package.json

确保您有一个包含 sourcemaps 生成的构建脚本。

"scripts": {
    "build": "babel src -d dist --source-maps"
}

tasks.json

确保您有 任务VS Code 使用 npm 脚本构建。

{
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "build",
            "args": [ "run", "build" ],
            "isBuildCommand": true
        }
    ]
}

launch.json

将脚本配置为在启动前构建,使用preLaunchTask,从源入口点启动program,但使用outDir 指向 dist 文件夹并启用 sourceMaps

{
    "name": "Launch",
    "type": "node",
    "request": "launch",
    "program": "${workspaceRoot}/src/server.js",
    "stopOnEntry": false,
    "args": [],
    "cwd": "${workspaceRoot}",
    "preLaunchTask": "build",
    "runtimeExecutable": null,
    "runtimeArgs": [ "--nolazy" ],
    "env": {
        "NODE_ENV": "development"
    },
    "externalConsole": false,
    "sourceMaps": true,
    "outDir": "${workspaceRoot}/dist"
}

现在,每次您按 F5babel 转译都会在节点进程启动之前运行,但所有源映射都会同步。有了它,我可以使用断点和所有其他调试器。

从 1.9 版开始,VS Code 默认会自动尝试使用源映射,但如果转译后的文件与源文件不在同一文件夹中,则必须指定 outFiles

例如,这里是相关文件。在这种情况下,babel 正在从 src 文件夹转译到 lib 文件夹。

注意: package.json.vscode/tasks.json 中的条目仅在您希望 VS Code 在调试前转换文件时才需要。


.vscode/launch.json

Ctrl+Shift+P,>Debug: Open launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "program": "${workspaceRoot}/lib/index.js",
            "cwd": "${workspaceRoot}",
            "preLaunchTask": "build",
            "outFiles": [
                "${workspaceRoot}/lib/**.js"
            ]
        }
    ]
}

注意: 如果您还在 package.json.vscode/tasks.json 中设置了 build 任务,则仅指定 preLaunchTask


package.json

Ctrl+P,package.json

{
  "scripts": {
    "build": "babel src -d lib -s"
  },
  "devDependencies": {
    "babel-cli": "^6.23.0",
    "babel-preset-env": "^1.1.10"
  }
}

注意:您可以使用不同版本的babel-cli和不同的babel预设。


.vscode/tasks.json

Ctrl+Shift+P,>Tasks: Configure Task Runner

{
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "build",
            "args": ["run", "build"],
            "isBuildCommand": true
        }
    ]
}

官方 VS 代码文档

来源地图

VS Code 的 Node.js 调试器支持 JavaScript 源映射,这有助于调试转译语言,例如TypeScript 或 minified/uglified JavaScript。使用源映射,可以单步执行或在原始源中设置断点。如果原始源不存在源映射,或者源映射已损坏且无法在源与生成的源之间成功映射 JavaScript,则断点显示为未验证(灰色空心圆圈)。

可以使用两种内联生成源映射:

  • 内联源映射:生成的JavaScript文件包含源映射作为末尾的数据URI(而不是通过文件URI引用源映射) .
  • 内联源:源映射包含原始源(而不是通过路径引用源)。

VS Code 支持内联源映射内联源

源映射功能由 sourceMaps 属性控制,从 VS Code 1.9.0 开始默认为 true。这意味着节点调试总是尝试使用源映射(如果它能找到任何源映射),因此您甚至可以使用 program 属性指定源文件(例如 app.ts)。

如果出于某种原因需要禁用源映射,可以将 sourceMaps 属性设置为 false

如果生成的(转译的)JavaScript 文件不在其源旁边而是在单独的目录中,您必须通过设置 outFiles 属性帮助 VS Code 调试器找到它们。此属性采用多个 glob 模式来包含和排除生成的 JavaScript 文件集中的文件。每当您在原始源中设置断点时,VS Code 都会尝试在 outFiles.

指定的文件中查找生成的 JavaScript 代码

由于不会自动创建源映射,因此您必须配置用于创建它们的转译器。对于 TypeScript,这可以通过以下方式完成:

tsc --sourceMap --outDir bin app.ts

这是 TypeScript 程序的相应启动配置:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch TypeScript",
            "type": "node",
            "request": "launch",
            "program": "app.ts",
            "outFiles": [ "bin/**/*.js" ]
        }
    ]
}

Source

不需要用@babel/node

转译

基本设置(源地图 - 始终)

注意 .babelrc 中的 sourceMapsretainLines 选项:

{
  "presets": [
    "@babel/preset-env"
  ],
  "sourceMaps": "inline",
  "retainLines": true
}

然后在launch.json:

{
  "type": "node",
  "request": "launch",
  "name": "Debug",
  "program": "${workspaceFolder}/index.js",
  "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/babel-node",
  "runtimeArgs": [
    "--nolazy"
  ]
}

高级设置(源地图 - 仅限开发)

您可以调整以上内容,以便仅在开发模式下生成 source-maps/retainLines:

{
  "presets": [
    "@babel/preset-env"
  ],
  "env": {
    "development": {
      "sourceMaps": "inline",
      "retainLines": true
    }
  }
}

并且:

{
  "type": "node",
  "request": "launch",
  "name": "Debug",
  "program": "${workspaceFolder}/index.js",
  "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/babel-node",
  "runtimeArgs": [
    "--nolazy"
  ],
  "env": {
    "BABEL_ENV": "development"
  }
}

备注

  • 目前 "type": "pwa-node" 不适用于此设置。
  • 对于"--nolazy"see this
  • "BABEL_ENV": "development" - 除非 different value is set 默认是 development,所以在启动配置中添加这个不是必需的(但确实使事情更明确)。

这是对我有用的(None 其他解决方案对我有用 vscode v1.33):

./project.json

"scripts": {
  "build": "babel src -d dist --source-maps",
},

.vscode/task.json

{
  "version": "2.0.0",
  "tasks": [{
    "label": "build-babel",
    "type": "npm",
    "script": "build",
    "group": "build"
  }]
}

.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [{
    "type": "node",
    "request": "launch",
    "preLaunchTask": "build-babel",
    "name": "Debug",
    "program": "${workspaceRoot}/src/server.js",
    "outFiles": ["${workspaceRoot}/dist/**/*.js"]
  }]
}

我的案例 (VSCode 1.36.0) 缺少的是源映射路径的覆盖:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Debug",
            "program": "${workspaceRoot}/src/cli/index.js",
            "sourceMaps": true,
            "sourceMapPathOverrides": {
                "*": "${workspaceRoot}/src/*"
            },
            "outFiles": [
                "${workspaceRoot}/lib/**/*.js"
            ]
        }
    ]
}

编译是通过 gulp 管道调用的,源映射指的是 cli/index.js 而不是 src/cli/index.js。使用 sourceMapPathOverrides 重新映射修复了该问题。

将此配置添加到您的 launch.json、

{
"version": "0.2.0",
"configurations": [
    {   
        "cwd":"<path-to-application>",
        "type": "node",
        "request": "launch",
        "name": "babel-node debug",
        "runtimeExecutable": "<path-to-app>/node_modules/.bin/babel-node",
        "program": "<path-to-app-entry-file>/server.js",
        "runtimeArgs": ["--nolazy"]
    }
]
}

不要忘记在您的项目根目录中定义带有预设的 .babelrc 文件。另外 launch.json 中的 cwd 属性必须正确,否则 babel 编译器将无法找到 .babelrc 并且会出现编译错误。

    {
        "presets": ["@babel/preset-env"]
    }

运行 此配置将自动在默认端口(通常为 5000)上启动应用程序并附加到生成的调试端口。 除非你使用一些超旧的vscode

,否则源映射无需任何额外配置即可工作