VSCode 新手:通过 Docker 进行远程 Jest/Node 调试

Posted

技术标签:

【中文标题】VSCode 新手:通过 Docker 进行远程 Jest/Node 调试【英文标题】:VSCode Newbie: Remote Jest/Node debugging through Docker 【发布时间】:2019-04-01 10:58:01 【问题描述】:

我最近从 Vim 切换到 VSCode,我正在尝试为通过 docker 运行的开玩笑测试设置 VSCode 调试。

调试工作......有点。如果我想运行 Jest 测试并激活断点,我需要:

    插入断点 通过下面的vscode-jest-testslaunch.json 任务开始运行相关的笑话测试 在测试套件遇到断点之前快速执行Docker: Attach To Node

显然不理想 - 我希望确保 VSCode 在运行 vscode-jest-tests 时自动附加到调试器。简而言之:在通过 Docker 运行 Jest 测试时,是否有一种简单的方法可以附加 VSCode 调试器?

这是我当前的 launch.json 和 package.json 文件。非常感谢任何帮助:

launch.json


  "version": "0.2.0",
  "configurations": [
    
      "type": "node",
      "request": "attach",
      "name": "Docker: Attach to Node",
      "port": 9229,
      "address": "localhost",
      "localRoot": "$workspaceFolder",
      "remoteRoot": "/www",
      "protocol": "inspector"
    ,
    
      "type": "node",
      "request": "launch",
      "name": "vscode-jest-tests",
      "runtimeExecutable": "npm",
      "runtimeArgs": [ "run", "test:debug" ],
      "address": "127.0.0.1",
      "port": 9229,
      "breakOnLoad": true,
      "restart": true,
      "timeout": 10000,
      "localRoot": "$workspaceFolder",
      "remoteRoot": "/www",
      "outFiles": [
        "$workspaceFolder/dist/**/*.js"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    
  ]

package.json

#...
"scripts": 
  "test:debug": "docker exec -it kiva_api node --nolazy --inspect-brk=0.0.0.0:9229 node_modules/.bin/jest --runInBand --config=test/jest-e2e.json"

#...

PS:如果我从命令行运行 npm run test:debug 并打开一个 chrome 调试器窗口,Chrome 的调试器就可以正常工作

【问题讨论】:

【参考方案1】:

这是我的解决方案的截图,主要来自您的同一个问题。谢谢你的提问:)

首先在监视模式下启动jest (--watchAll),以便进程保持活动状态。 (在 sn-p 中,我假设 backend 容器通过 docker-compose 运行,端口 9229 暴露在主机上)

docker-compose exec backend \
  node --inspect=0.0.0.0:9229 -r tsconfig-paths/register -r ts-node/register \
  node_modules/.bin/jest --watchAll --runInBand 

现在在 VSCode .vscode/launch.json config 中添加一个配置以附加到正在运行的进程。注意:确保remoteRoot 适合您的设置。


  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    
        "type": "node",
        "request": "attach",
        "name": "Docker: Debug tests",
        "address": "127.0.0.1",
        "port": 9229,
        "trace": true,
        "restart": true,
        "timeout": 10000,
        "localRoot": "$workspaceFolder",
        "remoteRoot": "/app",
        "outFiles": [
            "$workspaceFolder/dist/**/*.js"
        ],
        "disableOptimisticBPs": true,            
        "internalConsoleOptions": "neverOpen",
        "continueOnAttach": true,
    ]

从这里开始,我已经能够正确地开发和调试我的代码了。

【讨论】:

每次我尝试这个我都会收到一个错误TypeError: Cannot read property 'alias' of undefined at /app/node_modules/jest-validate/build/validateCLIOptions.js:97:58。看来-r tsconfig-paths/register 给我带来了问题 不确定,您可以尝试从 shell(例如 docker-compose exec backend bash)启动容器并测试 jest 命令,直到它适用于您的设置【参考方案2】:

这是我使用 Docker 调试 Jest 测试的 launch.json 配置。


  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    
      "type": "node",
      "name": "Docker: Jest Tests",
      "request": "launch",
      "program": "$workspaceFolder/node_modules/.bin/jest",
      "args": [
        "--runInBand"
      ],
      "cwd": "$workspaceFolder",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "disableOptimisticBPs": true,
      "windows": 
        "program": "$workspaceFolder/node_modules/jest/bin/jest",
      ,
      "protocol": "inspector"
    
  ]

这个想法是在通过 VSCode 运行和调试之前启动 docker-compose 包括一个数据库(Postgres、MongoDB 等)和一个 api 应用程序。

【讨论】:

【参考方案3】:

一天之后,明白了。

VSCode 启动.json


  "type": "node",
  "name": "docker-jest",
  "request": "attach",
  "address": "0.0.0.0",
  "port": 9229,
  "localRoot": "$workspaceFolder",
  "remoteRoot": "/app", // Will depend on your setup
  "skipFiles": [
    "<node_internals>/**/*.js",
    "$workspaceFolder/node_modules/**/*.js"
  ],
  "internalConsoleOptions": "neverOpen",
  "presentation": 
    "reveal": "silent"
  
,

确保您的 docker 容器在端口 9229 打开的情况下运行。我使用tail -d /dev/null 来保持我的运行。我不会详细介绍 docker 设置,因为有很多关于该主题的在线资源。

然后进入docker容器

$ docker exec -it container_name /bin/bash

然后运行

$ node --inspect-brk=0.0.0.0:9229 --nolazy -r ./node_modules/ts-node/register ./node_modules/jest/bin/jest.js --config=./jest-config.json --runInBand

--runInBand 标志 is key 使其工作。

--runInBand 导致所有测试在父进程而不是子进程中运行。

你应该看到类似的东西

root@7a0ba832e7f9:/app# node --inspect-brk=0.0.0.0:9229 --nolazy -r ./node_modules/ts-node/register ./node_modules/jest/bin/jest.js --config=./jest-config.json --runInBand
Debugger listening on ws://0.0.0.0:9229/267bfe8c-dfa8-45e0-a86c-abcadbd97bea
For help, see: https://nodejs.org/en/docs/inspector

在您的 Jest .spec.ts 文件中设置断点并执行 docker-jest 调试器。


如果您仍然遇到问题,请确保您的应用尚未在同一端口上以调试模式运行。测试将继续执行,仅显示以下内容的短暂暂停;

Starting inspector on 0.0.0.0:9229 failed: address already in use

如果发生这种情况,只需将node 命令和launch.json 中使用的调试端口更改为其他内容并打开 docker 端口。

【讨论】:

以上是关于VSCode 新手:通过 Docker 进行远程 Jest/Node 调试的主要内容,如果未能解决你的问题,请参考以下文章

VSCode + docker + SSH实现远程连接服务器并进行开发

vscode如何直接远程到ubuntu虚拟机docker容器?vscode远程开发

VScode搭建docker环境

VScode搭建docker环境

VsCode远程调试,更改pythonpath指向docker容器的python解释器

VsCode轻松使用docker容器-Remote Containers