kidk.kr 강그루 블로그

크롬 개발자도구를 활용한 디버깅

Node.js 애플리케이션을 개발하면서 나는 그동안 cosole.log를 써서 디버깅을 하곤 했다. 서버는 보통 debug 같은 패키지를 써서 로그를 수집하곤 하는데, 내가 평소에 작성하는 로그는 이런식의 로그가 아닌 디버깅 과정에서 임시로 생성하는 로그이다. 물론 회사의 프로젝트에서는 tslint의 규칙1을 통해 테스트 단계에서 걸러내고 있지만, 이러한 lint 규칙을 우회할 수 있는 주석기능이 있기 때문에 까딱 잘못하면 (코드리뷰 없이 긴급 배포된다던가) 프로덕션에도 나갈 여지가 남아있다. 몇몇 어설픈 프로덕트들에서 개발자도구를 열어보면 개발하다 남은 로그가 보이는 경우가 있어서 딱히 좋은 습관은 아니라고 스스로 생각하고 있었다.

Node.js 개발자들의 디버깅 조사 출처: https://blog.risingstack.com/node-js-developer-survey-results-2016/

RisingStack에서 조사한 결과에서도 Node.js개발자들의 디버깅에는 console.log가 80%로 압도적으로 많이 쓰인다.

그동안 나의 디버깅하는 과정을 살펴보면 다음과 같았다.

  1. 버그가 의심되는 곳에 console.log를 추가하고 저장한다. 필요하다면 조건문을 삽입한다.
  2. 변경된 소스코드가 새로 빌드된다.
  3. 웹 브라우저가 hot-reload 혹은 서버가 재시작
  4. 상황을 재연하고 로그를 확인한다
  5. 문제가 해결되었다면 로그를 지우고, 그렇지 않으면 1로 다시 돌아간다.

이게 가벼운 애플리케이션일 때에는 큰 문제가 되지 않지만 리로딩할 때에도 매번 빌드가 일어나는 것이기 때문에 사실상 로직에 큰 변화가 없음에도 불구하고 오랜 시간을 빌드하는 경우2가 있다. 어느 순간 이런 소모적인 시간이 너무 아깝다고 생각이 들었고, 간단한 디버깅은 breakpoint와 watch를 사용해 디버깅을 하는 습관을 들이기로 결심했다.

Conditional Breakpoint

Breakpoint는 코드를 실행하는 도중에 멈출 수 있는 기능이다. 자바스크립트가 아닌 타입스크립트같은 언어로 개발하고 있다면 source map을 통해서 breakpoint를 사용할 수 있다. 이 source map을 기준으로 breakpoint를 설정하고, 실제 transpile3된 js코드에서 중단점이 작동한다. webpack을 예로 들면 TypeScript source map을 설정4 해줄 수 있다.

Breakpoint를 사용할 때 답답한 점은 추상클래스나 상위클래스에 breakpoint를 거는 경우이다. console.log를 사용하는 디버깅에서는 조건문으로 분기를 해서 특정 상황에서만 로그를 출력하는 식으로 디버깅했겠지만, breakpoint에도 그런 기능이 있을 것 같아 찾아보니 다음과 같이 conditional breakpoint 라는 기능이 있다.

크롬 개발자 도구에서 특정 상황에만 중단점 생성하기

이 기능을 활용하면 굳이 여러번 새롭게 빌드하지 않아도 다양한 경우에 대해 중단점을 걸어 볼 수 있다.

정리하자면 다음과 같이 작업 방식이 바뀐 셈이다. 물론 이 과정에서 디버깅때문에 새롭게 빌드되는 시간은 사라졌다.

  1. 버그가 의심되는 곳에 breakpoint를 생성한다. 필요하다면 conditional breakpoint를 생성한다.
  2. 이곳에서 관찰할 값(예전에 로그로 출력하던 값)을 watch에 등록한다.
  3. 새로고침 혹은 재실행
  4. 상황을 재연하고 watch값을 확인한다.
  5. 문제가 해결되었다면 breakpoint를 off하고, 그렇지 않으면 1로 다시 돌아간다.

ndb

ndbpuppeteer로 만들어진 Node.js를 위한 디버거다. VSCode를 이용해서 Node.js서버를 크롬 개발자도구로 디버깅하거나 node의 --inspect플래그로 디버깅하는 방식5은 번거로워서 잘 쓰지 않았었는데, ndb는 별다른 설정없이 설치와 실행만으로도 잘 쓸 수 있었다. ndb는 개인적으로 쓰고있기 때문에 일을 할 때는 $ ndb npm run start처럼 통째로 npm script를 실행하고 있다. ndb가 실행되면 headless chrome을 통해 앞서 다룬 것과 마찬가지로 크롬 개발자도구를 활용해 디버깅할 수 있다.

  1. no-console 

  2. 프로젝트가 mono-repo로 변경된 이후로 공통된 라이브러리를 수정하면 빌드가 3분씩이나 걸리는 경우도 있었다. 

  3. source to source compile 

  4. https://webpack.js.org/guides/typescript/#source-maps 

  5. --inspect