Node.js를 디버깅하는 방법에 대해서 몇 번 글을 썼다.
Node.js도 계속 발전하면서 디버깅도 점점 좋아지고 있다. 나는 console.log
로 로그를 남기면서 디버깅하는 걸 훨씬 좋아하는 편이지만 때로는 디버거를 통해서 문제를 찾아야 하는 경우도 있다. 위에서 쓴 대로 Node.js v6부터 V8의 네이티브 인스펙터가 들어오기 시작했고 이제 이 방식이 표준으로 자리 잡아서 다른 도구들도 대체되거나 인스펙터 방식으로 통일되었다.
Node.js 8.0.0부터는 v8-inspector를 완전히 지원하기 시작해서 기존에 사용하던 --debug
가 폐기되고 --inspect
로 통일되었고 node-inspect가 Node.js에 통합되었다. 이 글은 예제는 Node.js 8.0.0 이상에서 동작하고 지금은 8.3.0을 사용하고 있다. 자세한 내용은 Debugging Node.js Apps에 잘 나와 있다.
--inspect
와 --inspect-brk
bin/www
가 구동 파일인 간단한 Express 웹 애플리케이션이 있다고 하면 이를 시작할 때 --inspect
옵션을 주면 된다. --inspect-brk
를 사용하면 코드 첫 줄에서 멈추므로 처음부터 디버깅해야 할 때 유용하다.
$ node --inspect bin/www
Debugger listening on ws://127.0.0.1:9229/8e704347-66ea-428a-9502-4d23ba374f9f
For help see https://nodejs.org/en/docs/inspector
위 메시지를 보면 디버거가 열려있는 것을 볼 수 있다. 이는 V8의 인터페이스이므로 이를 지원하는 다른 도구는 어떤 것이라도 사용할 수 있지만 여기서는 크롬 개발자도구를 사용해 보자.
크롬 브라우저에서 <chrome://inspect/>에 접속하면 Remote Target에서 방금 실행한 Express 애플리케이션을 볼 수 있다.
디버깅할 타겟의 "inspect" 버튼을 클릭하면 크롬 개발자도구가 열리고 웹페이지에서 JavaScript를 디버깅하듯이 개발자 도구로 디버깅을 할 수 있다.
$ node --inspect bin/www
Debugger listening on ws://127.0.0.1:9229/8e704347-66ea-428a-9502-4d23ba374f9f
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
개발자 도구를 연결하면 터미널에서 Debugger attached.
라고 나온 것을 볼 수 있다.
기본 포트는 9229
인데 다른 포트를 사용하고 싶다면 --inspect=port
나 --inspect-brk=port
를 사용하면 된다.
node-inspect
node-inspect는 Node.js에 내장된 디버거로 --inpect
로 연 디버깅 포트에 접속해서 디버깅할 수 있는 디버거이다. 디버거는 node inspect [js 파일]
로 시작한다.(--inpect
대신 inspect
이다.)
$ node inspect bin/www
< Debugger listening on ws://127.0.0.1:9229/a95f8658-9536-40ee-8a09-57c9313f4947
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in bin/www:1
> 1 (function (exports, require, module, __filename, __dirname) {
2
3 /**
debug>
커맨드 라인에서 디버깅을 할 수 있는데 다음과 같은 명령어를 사용할 수 있다.
cont
,c
- 계속 실행한다.next
,n
- 다음 단계로 이동step
,s
- 단계 안으로 이동out
,o
- 단계 밖으로 이동
Break on start in bin/www:1
> 1 (function (exports, require, module, __filename, __dirname) {
2
3 /**
debug> next
break in bin/www:7
5 */
6
> 7 var app = require('../app');
8 var debug = require('debug')('express-test:server');
9 var http = require('http');
debug> step
break in internal/module.js:10
8 function require(path) {
9 try {
>10 exports.requireDepth += 1;
11 return mod.require(path);
12 } finally {
debug> out
break in app.js:28
26 app.use('/users', users);
27
>28 debugger;
29
30 // catch 404 and forward to error handler
debug>
위처럼 next
를 입력하면 다음 단계로 넘어가고 step
, out
으로 함수 안에 들어가거나 나올 수 있다. debugger;
를 코드에 넣어두면 브레이크 포인트로 쓸 수 있으므로 cont
를 입력하면 debugger;
를 만날 때까지 실행하고 멈춘다.
run
이나 restart
를 입력하면 처음부터 다시 실행할 수 있고 repl
을 입력하면 현 위치에서 코드를 실행해 보거나 원하는 변수를 출력해 볼 수 있다.
debug> cont
break in app.js:28
26 app.use('/users', users);
27
>28 debugger;
29
30 // catch 404 and forward to error handler
debug> repl
Press Ctrl + C to leave debug repl
> console.log(app.settings)
< { 'x-powered-by': true,
< etag: 'weak',
< 'etag fn': [Function: wetag],
< env: 'development',
< 'query parser': 'extended',
< 'query parser fn': [Function: parseExtendedQueryString],
< 'subdomain offset': 2,
< 'trust proxy': false,
< 'trust proxy fn': [Function: trustNone],
< view: [Function: View],
< views: '/Users/outsider/Dropbox/projects/temp/express-test/views',
< 'jsonp callback name': 'callback',
< 'view engine': 'jade' }
> undefined
>
좀 더 자세한 내용은 Debugger 문서를 참고하면 된다.
Comments