我们的应用程序是用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
在createServer()
呼叫内的任何线路上设置断点时,它们被报告为无效; 虽然我可以在空白行中设置断点.这可能是因为TypeScript编译剥离了空行,出于某种原因,VSCode只会将生成的JS中的行号识别为有效:
这是一个易于复制的人为例子,但总的来说,我认为我在设置断点的位置与实际设置的位置之间存在不匹配.
但是,当我打破debugger
语句时,VSCode从服务器获取TypeScript文件(该选项卡在新打开时显示"从源映射中只读内联"的行),然后我可以在其中正确设置断点:
这是一个令人不满意的情况,原因我不应该解释:杂乱我可以编辑的本地文件和断点工作的远程文件很麻烦,添加debugger
语句将涉及每次我需要一个新的断点时重新加载应用程序.
我一直在寻找这个问题,但关键字给了我至少十年冗长的GitHub问题.由于我并不熟悉ts节点,转换和源映射的内部结构,因此我很难推断出这里发生的事情,更不用说如何解决它了.根据我的理解,会发生什么是ts-node将TS编译为JS并在Docker容器内的临时文件中生成源映射,而VSCode无法访问它们.(这就是为什么我不知道如何设置例如outFiles
.)如果在封闭的问题中正确设置,我的场景也有一些暗示已被支持,但没有关于如何做到的线索.
有没有办法让这个工作,以便我可以实际在远程调试时在我的本地源中设置断点,并让它们在所述文件中命中,而不必恢复到TS到JS和源映射的预编译,所以我有后者可用本地?
您没有生成代码的源映射.所以我在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'. */ } }
现在它就像一个魅力