Как правильно установить точки останова при использовании VS Code для отладки приложения TypeScript, запускаемого с использованием ts-node в контейнере Docker? - PullRequest
0 голосов
/ 20 мая 2018

Наше приложение написано на 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 как допустимые:

line number mismatch between TS and JS

Это надуманный пример для простоты воспроизведения, но в общем случае будет несоответствие между тем, где, я думаю, я устанавливаю точки останова, и тем, где они на самом деле установлены.

Однако, когда я ломаюсь наdebugger, VSCode извлекает файл TypeScript (на вкладке написано что-то вроде строки «только для чтения, встроенная из исходной карты» при новом открытии) с сервера, и тогда я могу правильно установить в нем точки останова:

breakpoints in local vs. remote file

Это неудовлетворительная ситуация по причинам, которые мне не нужно было объяснять: манипулирование локальным файлом, который я могу редактировать, и удаленный файл, где работают точки останова, - это хлопот, идобавление операторов debugger потребовало бы перезагрузки приложения каждый раз, когда мне нужна новая точка останова.

Я искал проблему, но ключевой моментДайте мне по крайней мере десять длинных вопросов GitHub, начиная с давних времен.Так как я не очень хорошо знаком с внутренностями ts-узла, транспиляции и исходными картами, мне трудно рассуждать о том, что здесь происходит, тем более, как это исправить.Из того, что я понимаю, происходит то, что ts-node компилирует TS в JS и генерирует исходные карты во временных файлах внутри контейнера Docker, где VSCode не может получить к ним доступ.(Вот почему я не знаю, как установить, например, outFiles.) Были также некоторые намеки на то, что мой сценарий уже поддерживается, если он был правильно настроен в закрытых выпусках, но не знал, как это сделать.

Есть ли способ заставить это работать так, чтобы я мог фактически установить точку останова в моих локальных источниках при удаленной отладке, и заставить их попадать в указанные файлы, без необходимости возвращаться к предварительной компиляции TS для JS и исходных карт, так что у меня естьпоследний доступен локально?

1 Ответ

0 голосов
/ 25 мая 2018

Вы не генерируете исходную карту для кода.Поэтому я обновил ваш 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'. */
  }
}

, и теперь он работает как брелок

Debugging working

...