VS Code를 이용한 Electron 디버깅 | [object Object]

July 15, 2017

VS Code를 이용한 Electron 디버깅

Electron 1.7버전에서는 node.js 6.3에서 추가되었던 v8 inspector 프로토콜 지원이 도입되었다. 이는 이전 버전에서 쓰이던 디버깅 프로토콜 대신 v8의 디버깅 프로토콜을 이용해 Electron의 메인 프로세스를 추적할 수 있게 해 준다. 더불어 이 프로토콜의 지원은 메인 프로세스 디버깅을 훨씬 수월하게 만들어 주는데, Chromium과 동일한 프로토콜을 사용하기 때문에 Chrome의 개발자 도구를 그대로 이용할 수 있기 때문이다. 기존의 렌더러 프로세스는 (Chromium 프로세스이기 때문에 당연히) 개발자 도구를 이용했었기 때문에 프로세스의 구분 없이 일관된 디버깅 환경에서 작업이 가능하다. 간단하게 메인 프로세스를 --inspect 명령과 함께 실행한 다음 제공된 url에 접속하면 익숙한 개발자 도구에서 메인 프로세스의 상태를 디버깅 할 수 있다.

개발자 도구에서 메인 프로세스 코드에 Breakpoint를 설정할 수 있다.

이것만으로도 훌륭하지만, 새로운 프로토콜의 지원 덕분에 VS Code를 에디터로 사용하고 있다면 더 편리한 디버깅 환경을 이용할 수 있다. VS Code의 디버거는 Multi-target debugging을 지원하는데, 이는 원래 서버와 클라이언트 코드를 동시에 디버깅 하는 경우를 위해 만들어진 기능이다. Electron의 경우 이 기능을 이용하면 메인 프로세스와 렌더러 프로세스를 동시에 디버깅이 가능하다.

먼저 메인 프로세스를 실행하는 디버깅 구성을 추가한다.

{
   "type":"node",
   "request":"launch",
   "name":"Electron Main",
   "runtimeExecutable":"${workspaceRoot}/node_modules/.bin/electron",

   "args":[
      "${workspaceRoot}/main.js",
      "--remote-debugging-port=9333" //렌더러 프로세스의 디버깅 포트를 설정
   ],
   "protocol":"inspector" //v8 inspector 프로토콜을 사용하도록 지정
}

실행파일을 Electron으로 지정하는 것과 inspector 프로코콜을 사용하도록 지정하는 것, 그리고 렌더러 프로세스의 디버깅이 가능하도록 명령어를 추가하는 것 정도가 기본 구성과 다른 점이다.

다음으로는 렌더러 프로세스를 위한 구성을 추가한다.

{
   "type":"node",
   "request":"attach",
   "name":"Electron Renderer",
   "protocol":"inspector",
   "port":9333
}

주의할 부분은 렌더러 프로세스도 여전히 node.js 디버거를 사용한다는 점이다. VS Code에는 Chrome 디버깅용 확장이 출시되어 있는데, 이 확장은 각 디버거를 따로 실행할 때는 문제가 없으나 Multi-target 디버깅을 위해 메인 프로세스 실행과 렌더러 프로세스 디버깅을 동시에 실행하면 렌더러 프로세스에 디버거가 접속을 하지 못하는 문제가 있다. 내부적으로는 두 디버거 확장이 모두 같은 코어를 사용하기 때문에 기능상의 차이는 없다.

마지막으로 이 두 디버거를 동시에 실행할 수 있도록 compound 설정을 추가한 다음 이 디버깅 타겟을 실행하면 두 디버거를 동시에 실행하고 각각의 프로세스간 스택을 이동하면서 디버깅을 할 수 있게 된다.

"compounds":[
   {
      "name":"Electron",
      "configurations":[
         "Electron Main",
         "Electron Renderer"
      ]
   }
]

동시에 프로세스 사이 스택 및 Breakpoint를 추적

물론 이 기능은 이전의 node.js 디버깅 프로토콜을 이용해서도 가능하지만 (1.7이전 버전의 경우 legacy 프로토콜을 이용) 새로운 프로토콜을 이용하면서 Electron-prebuilt-compile에서의 Source map 지원 등 이전의 프로토콜에서 지원하기 다소 힘들었던 부분을 특별한 설정 없이 이용할 수 있다는 장점이 있다.

OJ Kwon