使用 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?
我们的应用程序是用 TypeScript 编写的并使用 Docker,为了避免通过 .js 文件来回传输,我们运行使用 ts-node 加载它以加载 .js 文件。直接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
}
}
/Docker文件
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)
(空行很重要,原因我稍后会展示,其中大约有 10 行完成了这项工作。)
您也可以在这里获取全部内容:https://github.com/millimoose/ts-node-breakpoints
我 运行 使用 docker-compose --up
,然后使用上述启动配置将其附加到调试器。当我尝试在 createServer()
调用中的任何行的 /src/index.ts
中设置断点时,它们被报告为无效;而我可以在空白行中设置断点。这大概是因为 TypeScript 编译去掉了空行,出于某种原因,VSCode 只会将生成的 JS 中的行号识别为有效:
这是一个为便于复制而设计的示例,但通常我认为设置断点的位置与实际设置断点的位置不匹配。
但是,当我中断 debugger
语句时,VSCode 从服务器获取 TypeScript 文件(选项卡在新打开时显示类似于 "read-only inlined from sourcemap" 的内容),然后我可以在其中正确设置断点:
由于我不必解释的原因,这是一个令人不满意的情况:兼顾我可以编辑的本地文件和断点工作的远程文件很麻烦,添加 debugger
语句将涉及重新加载每次我需要一个新的断点时应用程序。
我四处搜索这个问题,但关键字给了我至少 10 个冗长的 GitHub 问题,其范围可以追溯到几年前。由于我不太熟悉 ts-node、转译和源映射的内部结构,因此我很难理解这里发生了什么,更不用说如何修复它了。据我了解,发生的事情是 ts-node 将 TS 编译为 JS 并在 Docker 容器内的临时文件中生成源映射,其中 VSCode 无法访问它们。 (这就是为什么我不知道如何设置,例如 outFiles
。)如果在关闭的问题中正确设置,我的场景也有一些暗示已经得到支持,但不知道如何去做。
有没有办法让它工作,这样我就可以在远程调试时在我的本地源代码中设置一个断点,并让它们命中所述文件,而不必恢复到将 TS 预编译为 JS 和 sourcemaps 所以我在本地有后者吗?
您没有为代码生成源映射。所以我更新了你的 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'. */
}
}
现在它就像一个魅力
我们的应用程序是用 TypeScript 编写的并使用 Docker,为了避免通过 .js 文件来回传输,我们运行使用 ts-node 加载它以加载 .js 文件。直接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
}
}
/Docker文件
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)
(空行很重要,原因我稍后会展示,其中大约有 10 行完成了这项工作。)
您也可以在这里获取全部内容:https://github.com/millimoose/ts-node-breakpoints
我 运行 使用 docker-compose --up
,然后使用上述启动配置将其附加到调试器。当我尝试在 createServer()
调用中的任何行的 /src/index.ts
中设置断点时,它们被报告为无效;而我可以在空白行中设置断点。这大概是因为 TypeScript 编译去掉了空行,出于某种原因,VSCode 只会将生成的 JS 中的行号识别为有效:
这是一个为便于复制而设计的示例,但通常我认为设置断点的位置与实际设置断点的位置不匹配。
但是,当我中断 debugger
语句时,VSCode 从服务器获取 TypeScript 文件(选项卡在新打开时显示类似于 "read-only inlined from sourcemap" 的内容),然后我可以在其中正确设置断点:
由于我不必解释的原因,这是一个令人不满意的情况:兼顾我可以编辑的本地文件和断点工作的远程文件很麻烦,添加 debugger
语句将涉及重新加载每次我需要一个新的断点时应用程序。
我四处搜索这个问题,但关键字给了我至少 10 个冗长的 GitHub 问题,其范围可以追溯到几年前。由于我不太熟悉 ts-node、转译和源映射的内部结构,因此我很难理解这里发生了什么,更不用说如何修复它了。据我了解,发生的事情是 ts-node 将 TS 编译为 JS 并在 Docker 容器内的临时文件中生成源映射,其中 VSCode 无法访问它们。 (这就是为什么我不知道如何设置,例如 outFiles
。)如果在关闭的问题中正确设置,我的场景也有一些暗示已经得到支持,但不知道如何去做。
有没有办法让它工作,这样我就可以在远程调试时在我的本地源代码中设置一个断点,并让它们命中所述文件,而不必恢复到将 TS 预编译为 JS 和 sourcemaps 所以我在本地有后者吗?
您没有为代码生成源映射。所以我更新了你的 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'. */
}
}
现在它就像一个魅力