使用 VS Code 调试在 Docker 容器中使用 ts-node 运行的 TypeScript 应用程序时,如何能够正确设置断点?

Posted

技术标签:

【中文标题】使用 VS Code 调试在 Docker 容器中使用 ts-node 运行的 TypeScript 应用程序时,如何能够正确设置断点?【英文标题】:How to be able to set up breakpoints correctly when using VS Code to debug a TypeScript app run using ts-node in a Docker container? 【发布时间】:2018-10-30 00:05:43 【问题描述】:

我们的应用使用 TypeScript 编写并使用 Docker,为了避免往返 .js 文件,我们使用 ts-node 运行它以直接加载 .ts 文件。

不幸的是,这似乎让 VSCode 对设置断点的有效代码行感到困惑。

此问题体现在以下设置中:

/package.json


  "scripts": 
    "start": "node --inspect=0.0.0.0 --require ts-node/register src/index.ts"
  ,
  "dependencies": 
    "@types/node": "^10.1.2",
    "ts-node": "^6.0.3",
    "typescript": "^2.8.3"
  

/tsconfig.json


  "compilerOptions": 
    "target": "ES2017",
    "module": "commonjs", 
    "outDir": "./dist",
    "rootDir": "./src",    
    "esModuleInterop": true
  

/Dockerfile

FROM node

RUN mkdir /home/node/app
WORKDIR /home/node/app
COPY package.json /home/node/app
RUN npm install && npm cache clean --force
COPY . /home/node/app
CMD [ "npm", "start" ]

/docker-compose.yml

version: "3.4"

services:
  http:
    build: .
    ports:
      - "8000:8000"
      - "9229:9229"

/.vscode/launch.json


    "version": "0.2.0",
    "configurations": [
        
            "type": "node",
            "request": "attach",
            "name": "Attach",
            "address": "localhost",
            "port": 9229,
            "protocol": "inspector",
            "localRoot": "$workspaceFolder/src",
            "remoteRoot": "/home/node/app/src"
        
    ]

/src/index.ts

import createServer from "http";








const server = createServer((msg, res) => 
    res.writeHead(200, 'Content-Type': 'text/plain')
    res.end(msg.url)
    debugger
)

server.listen(8000)

(空行很重要,原因我稍后会说明,其中大约有十个可以完成这项工作。)

您也可以在这里获取全部内容:https://github.com/millimoose/ts-node-breakpoints

我使用docker-compose --up 运行它,然后使用上述启动配置通过调试器附加到它。当我尝试在/src/index.ts 调用中的任何行上设置断点时,它们被报告为无效;而我可以在空行中设置断点。这大概是因为 TypeScript 编译去掉了空行,并且由于某种原因,VSCode 只会将生成的 JS 中的行号识别为有效:

这是一个便于复制的人为示例,但总的来说,我认为设置断点的位置与实际设置的位置之间存在不匹配。

但是,当我中断 debugger 语句时,VSCode 会从服务器获取 TypeScript 文件(标签显示新打开时类似于“从源映射只读内联”的内容),然后我可以设置断点在其中正确:

由于我不应该解释的原因,这是一个令人不满意的情况:兼顾我可以编辑的本地文件和断点工作的远程文件是一件麻烦事,并且添加 debugger 语句将涉及每次我需要时重新加载应用程序一个新的断点。

我已经搜索过这个问题,但这些关键字给了我至少十个冗长的 GitHub 问题,这些问题可以追溯到几年前。由于我对 ts-node、transpilation 和 sourcemaps 的内部结构并不十分熟悉,因此我很难理解这里发生了什么,更不用说如何修复它了。据我了解,发生的情况是 ts-node 将 TS 编译为 JS 并在 Docker 容器内的临时文件中生成源映射,而 VSCode 无法访问它们。 (这就是为什么我不知道如何设置,例如outFiles。)如果在已关闭的问题中正确设置,也有一些暗示我的场景已经得到支持,但不知道如何设置。

有没有办法让它工作,这样我就可以在远程调试时在我的本地源中设置一个断点,并让它们在所述文件中命中,而不必恢复到将 TS 预编译为 JS 和源映射所以我有后者在本地可用?

【问题讨论】:

【参考方案1】:

您没有为代码生成源映射。所以我更新了你的tsconfig.json,如下所示


  "compilerOptions": 
    /* Basic Options */
    "target": "ES2017",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "outDir": "./dist",                        /* Redirect output structure to the directory. */
    "rootDir": "./src",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "sourceMap": true,
    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
  

现在它就像一个魅力

【讨论】:

我很确定我尝试了所有与源映射相关的标志的组合,但我会在一分钟内看到。可能是这完全掩盖了一个更具体到我的真实代码的不同问题。 @millimoose,可能没有,但不能说。你检查它,看看会发生什么。因为它在第一次尝试中对我有用 奇怪,当我只改变它时对我不起作用。我可能会被诅咒。 只是为了仔细检查一下:那是来自本地源的 index.ts,而不是从内联源映射加载的那个? 我在我的 mac 上运行了 vscode,并在我的 ubuntu 虚拟机上使用你的 dockerfile 运行了同一个文件夹。我还要确保您加载的某些插件会导致行为中断

以上是关于使用 VS Code 调试在 Docker 容器中使用 ts-node 运行的 TypeScript 应用程序时,如何能够正确设置断点?的主要内容,如果未能解决你的问题,请参考以下文章

使用 VS Code 调试在 Docker 容器中使用 ts-node 运行的 TypeScript 应用程序时,如何能够正确设置断点?

VS Code 没有为在 Docker 容器中运行的 Node 应用程序打断点

docker-compose 用于将 VS Code 中的 node.js 调试器附加到 WSL docker 中的节点进程

在 Ubuntu 上的 VS Code 中运行 NGC 容器

在 VS Code 中调试 dockerized Django 导致错误“等待启动器连接超时”

使用 debugpy 和 vs 代码在 docker 容器中调试 python 导致超时/连接被拒绝