🆚

【開発環境】TypeScript, Express, Docker, VScodeでリモートデバッグ

2025/01/19に公開

TL;DR

  • ExpressをVScodeでリモートデバッグしたい
  • サーバーサイドのDockerコンテナに、リモートデバッグ用のポート9229を開放する

ディレクトリ構成

  • Reactプロジェクトのapiパッケージ内にExpressがプロジェクトのある変な感じの構成?
  • frontend/, backens/のような一般的なパッケージ構成の場合、launch.json, tsconfig.jsonのディレクトリ指定部分とかをええ感じにしとって下さい
.vscode/
├── launch.json
docker/
├── backend.Dockerfile
├── frontend.Dockerfile
webapp/
└── src/(React)
    └── api/(Express)
        ├── index.ts
        └── tsconfig.json
docker-compose.yml

src

.vscode\launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Attach to Docker (Remote Debug)",
      "address": "localhost",
      "port": 9229,
      "localRoot": "${workspaceFolder}/webapp/src/api",
      "remoteRoot": "/app",
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}

docker\backend.Dockerfile

FROM node:20

WORKDIR /app

COPY webapp/src/api/package*.json ./

RUN npm install

COPY webapp/src/api ./

RUN npx tsc

WORKDIR /app/dist

EXPOSE 3000
EXPOSE 9229

CMD ["npx", "nodemon", "--inspect=0.0.0.0:9229", "index.js"]

webapp\src\api\index.ts

  • このファイルの記述方法は何でも良いと思いますが、僕はindex.tsはサーバー起動だけにして、設定とかはapp.tsで行う感じ
import app from "./app";
import { connectToSqlServer } from "./app";

const port = 3000;
(async () => {
  try {
    await connectToSqlServer();

    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });
  } catch (error) {
    console.error("Failed to start the server:", error);
    process.exit(1);
  }
})();

webapp\src\api\tsconfig.json

  • sourceMapを有効化しておく
{
  "compilerOptions": {
    "sourceMap": true,
    "target": "ES2020",
    "module": "CommonJS",
    "moduleResolution": "node",
    "outDir": "./dist",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true,
    "resolveJsonModule": true,
    "baseUrl": ".",
    "forceConsistentCasingInFileNames": true,
    "paths": {
      "*": ["node_modules/*"]
    }
  },
  "include": ["./**/*.ts"],
  "exclude": ["node_modules", "dist"]
}

webapp\src\api\package.json

  • nodemon, ts-nodeとか多分あった方がええけど他は知らん
npm install --save-dev nodemon ts-node
{
  "name": "api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch",
    "start": "NODE_ENV=development node dist/app.js",
    "dev": "nodemon dist/app.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.7.9",
    "cors": "^2.8.5",
    "dotenv": "^16.4.7",
    "express": "^4.21.2",
  },
  "devDependencies": {
    "@types/cors": "^2.8.17",
    "@types/express": "^5.0.0",
    "@types/node": "^22.10.5",
    "nodemon": "^3.1.9",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.3"
  }
}

docker-compose.yml

  • frontend, sqlsever, cosmosdbのコンテナとかもあるけど割愛
version: "3.8"
services:
  backend:
    build:
      context: .
      dockerfile: docker/backend.Dockerfile
    ports:
      - "3000:3000" # アプリケーション用ポート
      - "9229:9229" # デバッグ用ポート
    dns:
      - 8.8.8.8
      - 8.8.4.4
    volumes:
      - ./webapp/src/api:/app
      - /app/node_modules
    env_file:
      - .env
    depends_on:
      - sqlserver

実行

Docker起動

docker compose down --volumes --remove-orphans
docker compose build --no-cache
docker compose up

VScodeでデバッグ

  • デバッグのタブで構成選んでF5押下でデバッグ開始

Discussion