使用 VSCode 的 Typescript 断点

Luc*_*sca 6 debugging visual-studio-debugging source-maps typescript

我有一个来自generator-express-no-stress-typescript模板的Yeoman脚手架项目。我需要对其进行调试,就像使用 Visual Studio Code 进行“逐步执行打字稿代码”一样(不,这对我来说还不够)。console.log()

根据文档我只需要发出

npm run dev:debug
Run Code Online (Sandbox Code Playgroud)

然后附上VSCode。问题是:如果我这样做,VSCode 将无法绑定断点。如果我让调试器在第一个执行行 ( "stopOnEntry": true) 上停止,它将停止在生成的 JavaScript 代码中,而不是源 TypeScript 代码中,并且/但选项卡标题中的文件名以斜体显示“index.ts”(不是 .js) 。

这是dev:debugpackage.json 中的脚本目标:

"dev:debug": "nodemon --exec \"node -r ts-node/register --inspect-brk\" server/index.ts | pino-pretty",
Run Code Online (Sandbox Code Playgroud)

这是我的“附加”配置launch.json

    {
        "name": "Debug (Attach)",
        "port": 9229,
        "request": "attach",
        "cwd": "${workspaceFolder}",
        "sourceMaps": true,
        "skipFiles": ["<node_internals>/**"],
        "type": "node",
        // "outFiles": ["${workspaceFolder}/dist/**/*.js"],
    },
Run Code Online (Sandbox Code Playgroud)

由于这不起作用,我尝试了其他一些教程,其中一个(我不记得是哪一个)让我将以下配置添加到我的 launch.json 中:

   {
       "name": "Run and debug",
       "program": "${workspaceFolder}/server/index.ts",
       "request": "launch",
       "skipFiles": [
           "<node_internals>/**"
       ],
       "type": "node",
       // "outFiles": ["${workspaceFolder}/dist/**/*.js"],
       "runtimeArgs": ["-r", "ts-node/register", "--preserve-symlinks"],
       "runtimeExecutable": "node",
       "args": ["--inspect", "${workspaceFolder}/server/index.ts"],
       "cwd": "${workspaceFolder}",           
   }
Run Code Online (Sandbox Code Playgroud)

起初这看起来很有希望,但后来,当我尝试它时,它单步执行 JS 代码而不是 TS,就像上面的“调试(附加)”配置一样。

下面是调试器用来跟踪执行的生成的 JS 代码。请注意,它在其末尾的注释中包含源映射。

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
require("./common/env");
const server_1 = __importDefault(require("./common/server"));
const routes_1 = __importDefault(require("./routes"));
const models_1 = __importDefault(require("./api/models"));
const port = parseInt((_a = process.env.PORT) !== null && _a !== void 0 ? _a : '3000');
const syncdb = ((_b = process.env.SYNC_DB_SCHEMA_ON_STARTUP) !== null && _b !== void 0 ? _b : 'false') === 'true';
if (syncdb) {
    models_1.default.sequelize.sync({ force: true }).then(() => {
        console.log("DB Aggiornato");
    }).catch((err) => {
        console.log("Errore", err);
    });
}
exports.default = new server_1.default().router(routes_1.default).listen(port);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiL2hvbWUvbHVjaW8vbXlhcHAvc2VydmVyL2luZGV4LnRzIiwic291cmNlcyI6WyIvaG9tZS9sdWNpby9teWFwcC9zZXJ2ZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsd0JBQXNCO0FBQ3RCLDZEQUFxQztBQUNyQyxzREFBOEI7QUFDOUIsMERBQThCO0FBQzlCLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxNQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxtQ0FBSSxNQUFNLENBQUMsQ0FBQztBQUdsRCxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsbUNBQUksT0FBTyxDQUFDLEtBQUssTUFBTSxDQUFDO0FBRTdFLElBQUksTUFBTSxFQUFFO0lBQ1IsZ0JBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtRQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO1FBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzlCLENBQUMsQ0FBQyxDQUFDO0NBQ047QUFHRCxrQkFBZSxJQUFJLGdCQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsZ0JBQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAnLi9jb21tb24vZW52JztcbmltcG9ydCBTZXJ2ZXIgZnJvbSAnLi9jb21tb24vc2VydmVyJztcbmltcG9ydCByb3V0ZXMgZnJvbSAnLi9yb3V0ZXMnO1xuaW1wb3J0IGRiIGZyb20gJy4vYXBpL21vZGVscyc7XG5jb25zdCBwb3J0ID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuUE9SVCA/PyAnMzAwMCcpO1xuXG5cbmNvbnN0IHN5bmNkYiA9IChwcm9jZXNzLmVudi5TWU5DX0RCX1NDSEVNQV9PTl9TVEFSVFVQID8/ICdmYWxzZScpID09PSAndHJ1ZSc7XG5cbmlmIChzeW5jZGIpIHtcbiAgICBkYi5zZXF1ZWxpemUuc3luYyh7IGZvcmNlOiB0cnVlIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkRCIEFnZ2lvcm5hdG9cIik7XG4gICAgfSkuY2F0Y2goKGVycjogYW55KSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiRXJyb3JlXCIsIGVycilcbiAgICB9KTtcbn1cblxuXG5leHBvcnQgZGVmYXVsdCBuZXcgU2VydmVyKCkucm91dGVyKHJvdXRlcykubGlzdGVuKHBvcnQpOyJdfQ==
Run Code Online (Sandbox Code Playgroud)

我解码了 base64 源映射,它似乎包含我的源的正确路径,甚至源代码的副本:

{"version":3,"file":"/home/lucio/myapp/server/index.ts","sources":["/home/lucio/myapp/server/index.ts"],"names":[],"mappings":";;;;;;AAAA,wBAAsB;AACtB,6DAAqC;AACrC,sDAA8B;AAC9B,0DAA8B;AAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,IAAI,mCAAI,MAAM,CAAC,CAAC;AAGlD,MAAM,MAAM,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,yBAAyB,mCAAI,OAAO,CAAC,KAAK,MAAM,CAAC;AAE7E,IAAI,MAAM,EAAE;IACR,gBAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;QACzC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE;QAClB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAC;CACN;AAGD,kBAAe,IAAI,gBAAM,EAAE,CAAC,MAAM,CAAC,gBAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC","sourcesContent":["import './common/env';\nimport Server from './common/server';\nimport routes from './routes';\nimport db from './api/models';\nconst port = parseInt(process.env.PORT ?? '3000');\n\n\nconst syncdb = (process.env.SYNC_DB_SCHEMA_ON_STARTUP ?? 'false') === 'true';\n\nif (syncdb) {\n    db.sequelize.sync({ force: true }).then(() => {\n        console.log(\"DB Aggiornato\");\n    }).catch((err: any) => {\n        console.log(\"Errore\", err)\n  
Run Code Online (Sandbox Code Playgroud)

这是我的tsconfig.json,以防万一它很重要:

{
  "compileOnSave": false,
  "compilerOptions": {
    "inlineSourceMap": true, // added after answer below, still doesn't work
    "target": "ES2019",
    "lib": ["ES2020"],
    "strict": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "declaration": true,
    "moduleResolution": "node",
    "useUnknownInCatchVariables": false,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "noUnusedParameters": true,
    "noUnusedLocals": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "strictPropertyInitialization":false,
    "alwaysStrict": true,
    "outDir": "dist",
    "typeRoots": ["node_modules/@types"],
    "resolveJsonModule": true,
    "baseUrl": "."

  },
  "include": ["server/**/*.ts", "server/api/models/index.ts"],
  "exclude": ["node_modules", "./test/", "./dist"]
}
Run Code Online (Sandbox Code Playgroud)

npx ts-node --showConfig这是(在 beautifulcoder对他的答案的评论之后)的输出

{
  "ts-node": {
    "cwd": "/home/lucio/myapp",
    "projectSearchDir": "/home/lucio/myapp",
    "project": "/home/lucio/myapp/tsconfig.json"
  },
  "compilerOptions": {
    "target": "es2019",
    "lib": [
      "es2020"
    ],
    "strict": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "useUnknownInCatchVariables": false,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "noUnusedParameters": true,
    "noUnusedLocals": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "strictPropertyInitialization": false,
    "alwaysStrict": true,
    "outDir": "./.ts-node",
    "typeRoots": [
      "/home/lucio/myapp/node_modules/@types"
    ],
    "resolveJsonModule": true,
    "baseUrl": "./",
    "inlineSourceMap": false, // PLEASE NOTE: this is false even after I added `"inlineSourceMap": true` in tsconfig.json above
    "inlineSources": true,
    "noEmit": false
  }
}
Run Code Online (Sandbox Code Playgroud)

我已经搭建了一个新的最小示例生成器表达无压力打字稿项目,再次遵循记录的过程。例如

$ npm install -g yo generator-express-no-stress
$ yo express-no-stress ts-debug-test
Run Code Online (Sandbox Code Playgroud)

当被问到时,选择“OpenAPI 3”而不是“Swagger 2”,这就是我第一次搭建真实项目时所做的。如果您需要一个显示问题的最小示例,您也可以这样做,或者如果您愿意,也可以在 GitHub 上找到我的示例。我只向其中添加了 launch.json,您只需在第一行有意义的代码处设置断点即可。

所以现在我不知道下一步该做什么来调试我的代码......有任何线索吗?

Luc*_*sca 2

该问题是由我存储项目的路径中的符号链接引起的(真正的错误正在被触发),例如

/home/lucio/myapp -> /home/lucio/workspace/vscode/myapp
Run Code Online (Sandbox Code Playgroud)

真正的错误在 VSCode 中,在这里

直接的解决方法是避免项目文件夹路径中的符号链接。