개요
Node.js에서 디버깅은 문제를 재현 가능한 최소 단위로 축소하고, 실행 흐름과 상태를 관찰해 원인을 단정하는 과정임. 이 글은 디버깅 기본 원리와 함께 Node.js 환경에서 자주 쓰는 세 가지 방법인 Chrome DevTools, node-inspect CLI, VS Code 디버거 사용법을 정리함
문제를 명확히 하기
- 작성한 코드의 기대 동작 정의
- 실제 관측된 동작과의 차이 정리
- 실패 조건과 재현 절차 고정
문제 정의가 모호하면 디버깅 범위가 불필요하게 커짐. 입력, 환경 변수, 의존성 버전, 네트워크 상태 등 외부 요인도 고정하는 편이 좋음
다양한 가정과 빠른 배제
- API를 올바른 개체와 메서드로 사용했는지 확인
- 오타, 잘못된 인수 순서, 잘못된 기본값 사용 여부 점검
- 코드 변경 이력이 해당 증상과 인과관계 있는지 검증
- 실제 값과 다른 상수를 가정해 추론하지 않았는지 점검
- 타인이 작성한 코드라면 의도와 계약을 먼저 파악
작게 만들고 자주 실행하는 전략 권장. 최소 동작 코어를 먼저 통과시키고, 점진적으로 수정·확장하며 각 단계에서 실패를 국소화함
디버거 기본 개념
Breakpoint 중단점. 실행을 특정 라인에서 멈춤. 코드에 debugger 구문을 넣거나 에디터에서 라인 왼쪽 클릭 등으로 설정
Watch 특정 변수나 표현식 값을 지속 관찰. 값 변화와 조건 만족 시점을 빠르게 확인하는 용도
예시
function fibonacci(n) { if (n < 2) return n; const result = fibonacci(n - 1) + fibonacci(n - 2); return result; }watch에 result === 5 추가 시 false에서 true로 전환되는 시점을 즉시 파악 가능
Call Stack 현재 호출 중인 함수 스택 추적. 어디에서 무엇이 호출되었는지 역추적 가능
Step controls
- Continue 다음 중단점까지 진행
- Step over 현재 라인 실행, 함수 내부는 건너뜀
- Step into 함수 내부로 진입, 라인 단위 실행
- Step out 현재 함수 나머지를 실행하고 리턴 지점에서 멈춤
Chrome DevTools로 Node.js 디버깅
Node 8부터 V8 Inspector를 정식 지원. 기존 –debug 플래그는 폐기되고 –inspect 계열로 통일됨. 가장 간단한 진입 방법은 다음과 같음
초기 진입
- node –inspect app.js 실행
- 처음 라인부터 멈추려면 node –inspect-brk app.js 사용
실행 로그 예시
Debugger listening on ws://127.0.0.1:9229/... For help, see: https://nodejs.org/en/docs/inspectorChrome 접속
- 주소창에 chrome://inspect 입력 후 Devices 화면으로 이동
- Remote Target에서 실행 중인 Node 프로세스를 선택해 inspect 진입
유의사항
- 기본 디버그 포트는 9229. 충돌 시 –inspect=127.0.0.1:0 같은 동적 포트를 사용해 충돌 회피
- 외부 접근이 가능한 호스트로 열지 않기. 로컬 호스트 바인딩 유지 권장
node-inspect CLI 사용
터미널 기반 디버깅이 필요하면 내장 CLI 디버거 사용
진입
- node inspect 파일명
기본 명령
- cont 또는 c 계속 실행
- next 또는 n 다음 라인으로 이동
- step 또는 s 함수 내부로 진입
- out 또는 o 현재 함수에서 빠져나옴
- run 또는 restart 재실행
- repl 현 위치 컨텍스트에서 표현식 평가
임시 중단점
- 코드에 debugger 구문 삽입 후 cont로 진행하면 해당 지점에서 중단
CLI는 GUI 없이도 재현 자동화 스크립트나 원격 SSH 환경에서 빠르게 상태를 확인하기에 유용함
VS Code에서 디버깅
VS Code는 Node 디버거를 기본 통합 제공. 대부분은 실행 메뉴에서 F5로 시작 가능
첫 실행
- 실행 > 디버깅 시작 또는 F5 선택
- launch.json이 없으면 환경 선택 팝업에서 Node.js 선택
launch.json 역할
- 실행 파일, 인자, 환경 변수, 작업 디렉터리, 포트 등 디버깅 구성을 선언적으로 관리
- 팀 단위로 동일한 재현 절차를 공유하는 데 유용
최소 설정 예시
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceFolder}/app.js" } ] }단축키
- 계속 또는 일시중지 F5
- 단위 실행 F10
- 단계 진입 F11
- 단계 빠져나오기 Shift+F11
- 다시 시작 Ctrl+Shift+F5
- 중지 Shift+F5
실전 팁과 주의사항
- 프로덕션에서 –inspect 노출 금지. 로컬 또는 제한된 네트워크에서만 사용
- 포트 고정이 필요 없으면 –inspect=127.0.0.1:0로 충돌 회피
- debugger 구문과 남은 중단점은 커밋 전에 제거 또는 비활성화
- 비동기 흐름 디버깅 시 콜 스택에서 프레임을 좁히고, 필요 시 로그와 디버거를 병행하여 원인 단정
- 재현이 어려운 케이스는 입력과 환경을 고정하고 최소 재현 코드를 별도 파일로 분리해 분석
마무리
디버깅의 핵심은 문제를 작게 만들고 실행 흐름과 상태를 검증 가능한 근거로 좁혀가는 것임. Node.js에서는 Chrome DevTools, node-inspect, VS Code 세 가지 축만 숙지해도 대부분의 서버 사이드 이슈를 빠르고 안전하게 추적 가능함. 도구는 상황에 맞게 고르되, 재현성 확보와 가설 검증 루프를 짧게 유지하는 것이 성패를 가름함