IE11을 이용한 JavaScript 디버깅 08, F12 개발자 도구 디버거 창 Part 4

등록일시: 2019-02-26 08:00,  수정일시: 2019-02-26 08:00
조회수: 8,904

브라우저를 기반으로 한 웹 응용 프로그램 개발 생태계에서 클라이언트 측 개발의 난이도와 복잡성은 이미 서버 측에 못지 않습니다. 이런 어려움에 대한 대표적인 방안 중 하나로 대부분의 최신 브라우저들은 수 년 전부터 F12 개발자 도구를 제공하고 있습니다. F12 개발자 도구를 활용하면 직면한 문제점을 해결할 수 있는 실마리를 손쉽게 발견할 수 있는 경우가 많습니다. 그러나 초보자나 갑자기 웹 환경에서 작업하게 된 다른 언어의 전문가가 F12 개발자 도구에 부담 없이 접근할 수 있게 실질적인 도움을 제공하는 자료는 아직 많이 부족합니다.

이 시리즈에서는 가장 단순한 F12 개발자 도구를 갖고 있는 IE11을 사용해서 JavaScript를 디버깅하는 초보적인 수준의 방법을 소개합니다. F12 개발자 도구에서 어떤 기능의 도구가 제공되며 그 도구를 어떤 경우에 어떤 방식으로 활용할 수 있을지 간단히 경험해보고, 자신이 선호하는 다른 최신 브라우저에서 그에 대응하는 기능을 찾아서 사용할 수 있는 시작점이 되는 것이 본 시리즈의 목표입니다.

시리즈 목차: IE11을 이용한 JavaScript 디버깅

들어가기 전에

지금까지 세 차례에 걸쳐서 F12 개발자 도구의 디버거 창이 제공하는 기능들을 활용하여 디버깅을 수행하는 가장 기본적인 방법을 알아봤습니다. 그렇지만 아직 디버거 창의 다양한 기능들을 모두 살펴본 것은 아닙니다. 물론 불필요한 기능까지 모조리 알고 있어야만 하는 것은 아니지만, 그 밖에도 주목할만한 기능들이 몇 가지 더 남아 있습니다. 본문에서는 그 중 먼저 중단점 탭과 호출 스택 탭의 활용법을 조금 더 자세하게 살펴보도록 하겠습니다.

예제 코드 살펴보기

지금까지 계속 예제로 사용했던, 단어에 적절한 조사를 덧붙여주는 예제 HTML 파일을 본문에서도 주요 예제로 사용합니다. 이 예제에 대한 자세한 설명은 여기를 참고하시기 바랍니다. 그 밖에 추가적으로 사용되는 예제들에 대해서는 그때마다 별도로 설명하도록 하겠습니다. (새 창에서 보기)

본문에서는 네 가지 예제를 번갈아 가면서 테스트하므로 헛갈리지 않게 주의하시기 바랍니다.

중단점 탭

중단점 탭은 그 이름처럼 중단점을 (그리고 잠시 뒤에 살펴볼 추적점을) 관리하는 탭입니다. 설정되어 있는 중단점들을 목록으로 살펴볼 수 있고 특정 중단점을 클릭해서 해당 중단점이 설정된 원본 코드로 즉시 이동할 수도 있습니다.

F12 개발자 도구 - 중단점 탭 - 중단점 목록 및 원본 코드 찾기

더 이상 필요 없어진 중단점을 제거하거나 임시로 비활성시킬 수도 있습니다. 먼저 중단점 탭에서 중단점을 삭제하려면 중단점 항목 위에 마우스를 올리면 나타나는 이 중단점 삭제 버튼을 클릭하거나, 마우스 오른쪽 버튼으로 중단점 항목을 클릭하고 컨텍스트 메뉴에서 삭제를 선택하면 됩니다. 물론 이전 글들에서 언급했던 것처럼 원본 소스 탭의 좌측 여백에 설정된 빨간원을 한 번 더 클릭하거나 F9 키를 누르는 등의 방법도 여전히 유효합니다.

F12 개발자 도구 - 중단점 탭 - 중단점 삭제

중단점을 삭제하는 대신, 잠시 동안만 비활성시킬 수도 있습니다. 중단점 항목 좌측에 위치한 체크박스를 클릭해서 선택을 해제하거나, 마우스 오른쪽 버튼으로 중단점 항목을 클릭하고 컨텍스트 메뉴에서 사용 안 함을 선택하면 됩니다. 그 상태에서 체크박스를 한 번 더 클릭하거나 컨텍스트 메뉴에서 사용을 선택하면 중단점이 다시 활성화됩니다. 참고로 비활성된 중단점은 속이 비어 있는 빨간원으로 표현됩니다.

F12 개발자 도구 - 중단점 탭 - 중단점 비활성

또한 중단점 탭 우측 상단에 위치한 모든 중단점 설정/해제 버튼과 모두 삭제 버튼을 이용해서 모든 중단점을 한 번에 활성/비활성시키거나 삭제할 수도 있습니다.

F12 개발자 도구 - 중단점 탭 - 모든 중단점 활성/비활성 및 삭제

마지막으로 중단점 탭의 목록에서 마우스로 중단점 항목을 선택할 때 탐색기 등에서와 동일한 방식으로 Ctrl 키나 Shift 키를 이용해서 여러 개의 중단점 항목을 동시에 선택할 수도 있습니다. 그 상태에서 작업을 수행하면 선택된 중단점 항목들을 일괄로 활성/비활성시키거나 삭제할 수 있습니다.

그런데 한 가지 재미있는 점은 중단점 탭 자체적으로는 일반적인 중단점을 추가할 수 있는 방법은 제공되지 않는다는 사실입니다. 이는 기술적으로 불가능해서라기 보다는, 중단점을 설정하고자 하는 원본 소스 코드의 유효한 특정 위치를 손쉽게 지정할 수 있는 직관적인 UI가 딱히 마땅치 않기 때문으로 보입니다. 그냥 원본 소스 탭에서 좌측 여백을 한 번 클릭하기만 하면 되는 더 간단한 방법을 제공해주니 말입니다.

그 대신 중단점 탭에서는 일반적인 중단점에 보다 세부적인 조건을 지정하거나 특수한 형태의 중단점을 추가할 수 있는 방법을 제공해줍니다. 바로 지금부터 살펴볼 조건부 중단점이벤트 중단점, 그리고 이벤트 추적점 등이 그것입니다.

노트

'일반적인 중단점'이라는 별도의 공식 용어가 존재하는 것은 아닙니다. 단지 설명 상의 편의를 위해 '조건부 중단점' 등과 구분되는 단어를 본문에서 임의로 선정한 것입니다.

조건부 중단점

지금까지 본 시리즈에서 살펴본 모든 중단점들은 일반적인 중단점입니다. 이런 일반적인 중단점에 보다 구체적인 조건을 지정해서 특정 조건을 만족하는 경우에만 코드 실행을 중단하는 조건부 중단점을 설정할 수 있습니다.

가령 다음과 같이 var result = attachPostposition(data[i]) 구문에 일반적인 중단점을 설정했다고 가정해보겠습니다.

F12 개발자 도구 - 중단점 탭 - 일반적인 중단점

당연한 얘기지만 이 중단점을 사용해서 디버깅을 수행하는 데는 아무런 문제도 없습니다. 그러나 상황에 따라서는 매우 번거로울 수가 있습니다. 예를 들어 배열의 현재 항목 값(data[i])이 '배'인 경우에만 코드를 중단하고 싶은 경우를 떠올려보면 무슨 말인지 쉽게 이해하실 수 있을 것입니다. 그나마 본문의 예제는 배열의 항목이 4개뿐이지만 수백, 수천 개의 항목이 담겨있는 배열이라고 생각해보면 끔찍합니다. 바로 이런 경우에 조건부 중단점을 유용하게 활용할 수 있습니다.

조건부 중단점을 설정하려면 중단점 탭에서 중단점 항목 위에 마우스를 올리면 나타나는 이 중단점에 조건 추가 버튼을 클릭하거나, 마우스 오른쪽 버튼으로 중단점 항목을 클릭하고 컨텍스트 메뉴에서 조건...을 선택합니다. 또는 중단점 항목을 선택한 다음 단축키인 Alt+F9 키를 눌러도 됩니다.

F12 개발자 도구 - 중단점 탭 - 조건부 중단점

그러면 다음과 같은 조건부 중단점 팝업이 나타나는데, 조건 입력란에 평가할 조건식을 입력하고 확인 버튼을 클릭하면 일반적인 중단점이 조건부 중단점으로 변경됩니다. 가령 이번 예제에서는 data[i] == "배"라는 조건식 정도라면 적당할 것입니다. 앞으로 이 중단점은 지정한 조건식이 true인 경우에만 코드 실행을 중단하게 됩니다.

F12 개발자 도구 - 중단점 탭 - 조건부 중단점 팝업

이 상태에서 실제로 디버깅을 수행해보면 다음과 같이 지정한 조건식을 만족하는 경우에만 조건부 중단점에서 코드 실행이 중단됩니다. 즉 전체 코드가 실행되는 동안, 네 번이 아닌 단 한 번만 코드가 중단됩니다. 조사식 탭을 살펴보면 data[i]의 현재 값이 '배'라는 사실을 확인할 수 있습니다. 각자 직접 테스트해 보시기 바랍니다.

F12 개발자 도구 - 중단점 탭 - 조건부 중단점 테스트

만약 조건부 중단점을 원래대로 일반적인 중단점으로 되돌리고 싶다면, 다시 조건부 중단점 팝업에서 조건식을 지우기만 하면 됩니다. 참고로 조건부 중단점은 단순한 빨간원이 아닌 더하기 표시가 있는 빨간원으로 표현되므로 일반적인 중단점과 쉽게 구분할 수 있습니다.

사실 조건부 중단점중단점 탭 외에도 원본 소스 탭에서 컨텍스트 메뉴를 통해서도 설정할 수 있습니다. 먼저 일반적인 중단점을 설정한 다음, 동일하게 마우스 오른쪽 버튼을 클릭하고 컨텍스트 메뉴에서 조건...을 선택하면 됩니다.

F12 개발자 도구 - 중단점 탭 - 조건부 중단점

문제는 이런 방식으로 조건부 중단점 팝업을 열면 자꾸만 멋대로 팝업이 닫힌다는 것입니다. 사실 이뿐만 아니라 중단점 탭에서 컨텍스트 메뉴를 이용해서 같은 작업을 수행해도 역시 동일하게 조건부 중단점 팝업이 제멋대로 닫힙니다. 그런 경우에는 단축키나 이 중단점에 조건 추가 버튼을 사용하시기 바랍니다. 이는 더 이상 개선되지 않는 IE11의 한계라고 말할 수 있을 것입니다.

이벤트 중단점

이벤트 중단점은 특정 이벤트가 발생할 때 코드 실행이 중단되는 형태의 중단점입니다. 그렇기 때문에 이벤트 중단점을 지정할 때는 어떤 원본 코드의 몇 번째 줄, 몇 번째 글자를 지정하는 대신, 코드 실행을 중단하고자 하는 이벤트를 지정하게 됩니다. 이벤트 중단점을 설정하려면 중단점 탭에서 이벤트 중단점 추가 버튼을 클릭합니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 중단점

그러면 다음과 같은 이벤트 중단점 추가 팝업이 나타나는데, 이벤트 드롭다운 박스에서 원하는 이벤트를 선택하고 확인 버튼을 클릭하면 이벤트 중단점이 설정됩니다. 이때 조건 입력란에 평가할 조건식까지 함께 입력하면 조건부 이벤트 중단점이 됩니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 중단점 추가 팝업

직접 이벤트 중단점을 설정해서 실제로 동작 여부를 테스트해 보도록 하겠습니다. 다음은 이벤트 중단점을 살펴보기 위한 간단한 예제 HTML 파일입니다. 간단한 버튼이 세 개 존재하는데, 첫 번째 버튼에는 정상적인 onclick 이벤트 핸들러가 설정되어 있고, 두 번째 버튼에는 onclick 특성 자체가 존재하지 않으며, 세 번째 버튼은 onclick 특성은 존재하지만 그 값이 비어 있습니다. (새 창에서 보기)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>디버거 - 이벤트 중단점 예제</title>
    <style>
      body {
        font-size: 12px;
        font-family: Tahoma;
      }
      input[type="button"] {
        display: block;
        width: 150px;
        height: 30px;
        margin: 5px;
      }
    </style>
  </head>
  <body>
    <input type="button" value="Button 1." onclick="fnButton1();" />
    <input type="button" value="Button 2." />
    <input type="button" value="Button 3." onclick="" />

    <script>
      function fnButton1() {
        console.log("It's from Button 1.");
      }
    </script>
  </body>
</html>

이 예제 HTML 파일을 IE11에서 열고 이벤트 중단점 추가 팝업을 띄운 다음, 이벤트 드롭다운 박스에서 기본값인 마우스 이벤트를 선택하고 추가 버튼을 클릭합니다. 그러면 다음과 같이 이벤트 중단점이 추가됩니다. 참고로 이벤트 중단점은 번개 표시가 있는 빨간원으로 표현됩니다. 당연한 얘기지만 이벤트 중단점의 경우 중단점 탭에서만 관리할 수 있으며, 원본 소스 탭에는 어떠한 표시도 나타나지 않습니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 중단점 테스트

자세히 살펴보면 구체적인 이벤트를 지정하지 않고 마우스와 관련된 대표적인 이벤트들을 포괄하는 마우스 이벤트를 선택했기 때문에 click, dblclick, mousedown, mouseup, contextmenu 이벤트가 모두 중단점 대상으로 지정된 것을 확인할 수 있습니다.

이제 첫 번째 버튼을 클릭해봅니다. 그러면 다음과 같이 첫 번째 버튼을 정의한 HTML 태그의 onclick 특성에서 코드 실행이 중단됩니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 중단점 테스트

이제 이 상태에서 툴 바의 한 단계씩 코드 실행 버튼을 클릭하거나 단축키인 F11 키를 눌러서 바인딩 된 JavaScript 함수의 내부로 이동하여 탐색을 할 수 있습니다.

마우스로 계속 버튼을 클릭하거나 단축키인 F5 키를 눌러서 디버거를 빠져나갑니다. 그리고 이번에는 두 번째 버튼을 클릭해봅니다. 어떻게 예상하셨을지는 모르겠지만 두 번째 버튼 클릭에는 디버거가 전혀 반응하지 않음을 확인할 수 있습니다. 그러면 이번에는 마지막으로 세 번째 버튼을 클릭해봅니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 중단점 테스트

그러면 이번에도 디버거에서 코드 실행이 중단되기는 하는데 그 위치가 조금 엉뚱합니다. 즉 실제로는 존재하지 않는 가상의 onclick 함수에서 실행이 중단되는 것입니다. 언급했던 것처럼 이 세 번째 버튼을 정의하는 HTML 태그에는 onclick 특성이 존재하기는 하지만 그 값은 비어 있는 상태입니다. 이런 경우 IE11은 내부적으로 관리하는 가상의 대응 함수에서 코드 실행을 중단하는 것으로 보입니다. 마치 이벤트에 대한 각각의 HTML 특성을 하나의 코드 블럭으로 간주하는 듯 합니다.

지금까지 살펴본 결과로 미루어 짐작해 볼 수 있는 것은 이벤트 중단점이 정상적으로 동작하기 위해서는 설령 그 값은 비어있을지언정 디버거가 실행을 중단할 수 있는 구체적인 위치가 존재해야 한다는 사실입니다. 예를 들어 마우스 이벤트에는 click 이벤트 말고도 몇 가지 다른 이벤트들이 포함되어 있지만, 그에 대한 이벤트 핸들러가 설정되어 있지 않기 때문에 역시 디버거가 반응하지 않습니다. 실제로 oncontextmenu="fnButton1();" 같은 특성을 정의한 다음, 마우스 오른쪽 버튼으로 클릭해보면 디버거가 정상적으로 반응하는 것을 확인할 수 있습니다.

조금 아쉬운 점은 일단 이벤트 중단점을 만들고 난 뒤에는 지정한 이벤트를 변경할 수가 없다는 것입니다. 무조건 새로운 이벤트 중단점을 만들어야만 합니다. 중단점 탭에서 이벤트 중단점 항목을 선택한 다음, 이 중단점에 조건 추가 버튼을 클릭해보면 (비록 버튼의 아이콘이 마치 편집 기능인 것처럼 보일 수도 있지만), 이벤트 중단점 추가 팝업 대신 다음과 같이 조건부 중단점 팝업이 나타납니다.

F12 개발자 도구 - 중단점 탭 - 조건부 이벤트 중단점

이전 절에서 살펴봤던 조건부 중단점과 동일하게 조건 입력란에 평가할 조건식을 입력하고 확인 버튼을 클릭하면 이벤트 중단점조건부 이벤트 중단점으로 변경됩니다. 예를 들어 event.ctrlKey === true 같은 조건식을 입력해보겠습니다.

F12 개발자 도구 - 중단점 탭 - 조건부 중단점 팝업점

그러면 다음과 같이 작은 번개 표시가 추가된 더하기 표시가 있는 빨간원으로 조건부 이벤트 중단점이 만들어집니다.

F12 개발자 도구 - 중단점 탭 - 조건부 이벤트 중단점

다시 이전처럼 첫 번째 버튼을 클릭해보면 일반적인 상태에서는 디버거가 반응하지 않습니다. 대신 조건식을 만족시키기 위해 Ctrl 키를 누른 채로 버튼을 클릭해야만 디버거에서 코드 실행이 중지됩니다.

이와 같이 이벤트 중단점으로 설정할 수 있는 이벤트의 종류는 상당히 다양합니다. 다음 이미지는 설정 가능한 모든 이벤트들의 목록을 보여줍니다. (큰 이미지로 보기)

F12 개발자 도구 - 중단점 탭 - 조건부 이벤트 이벤트 목록

추적점

F12 개발자 도구의 디버거 창에서는 중단점 외에 추적점이라는 기능도 제공해줍니다. 의외로 이 기능을 잘 모르고 계신 분들이 많은데, 추적점을 한 마디로 설명하자면 코드를 작성하지 않고 설정하는 방식으로 지정하는 console.log() 함수 같은 기능입니다.

일반적인 추적점을 설정할 수 있는 방법은 단 한 가지 뿐입니다. 다음은 추적점을 설정하기 위해, 다시 단어에 적절한 조사를 덧붙여주는 예제 HTML 파일을 열고, jquery-3.3.1.js 파일에 정의된 $.trim() 메서드 정의의 내부 코드를 마우스 오른쪽 버튼을 클릭한 다음, 컨텍스트 메뉴에서 추적점 삽입을 선택하는 모습을 보여줍니다.

F12 개발자 도구 - 중단점 탭 - 추적점 설정

그러면 다음과 같이 추적할 메시지 팝업이 나타납니다. 추적 입력란에 출력할 메시지를 입력하고 확인 버튼을 클릭하면 추적점이 설정됩니다. 가령 이번 예제에서는 "Current text: " + text 라는 메시지를 입력했습니다.

F12 개발자 도구 - 중단점 탭 - 추적할 메시지 팝업

이렇게 설정된 추적점중단점 탭에 등록되어 지금까지 살펴본 다른 중단점들처럼 관리가 가능해집니다. 그러나 한 번 등록된 메시지는 추적점 항목 위에 마우스를 올리면 나타나는 추적 메시지 버튼을 눌러서 다시 추적할 메시지... 팝업을 띄워도 수정이 불가능하고 매번 다시 입력해야만 하므로 주의하시기 바랍니다. 참고로 추적점은 활성/비활성 여부와 상관없이 빨간 마름모로 표현됩니다.

F12 개발자 도구 - 중단점 탭 - 추적점

이제 버튼을 클릭해서 예제 HTML 파일의 코드를 다시 실행해보시기 바랍니다. 추적점에서는 코드 실행이 중단되지 않기 때문에 그대로 예제가 끝까지 실행될 것입니다. 다음은 예제를 실행하고 콘솔 창을 살펴본 모습을 보여줍니다.

F12 개발자 도구 - 콘솔 탭 - 추적점 결과

이처럼 추적점은 축소된 외부 라이브러리 등과 같이 console.log() 함수를 직접 추가로 작성하기에는 다소 부담스러운 경우에 유용합니다. 또는 운영 환경을 대상으로 디버깅을 수행할 때나 다른 사이트들을 분석할 때도 제법 쓸만합니다.

이벤트 추적점

이벤트 추적점이벤트 중단점추적점 버전입니다. 이벤트 중단점의 경우와 마찬가지로 메시지를 출력하고자 하는 이벤트를 지정하는 방식으로 설정할 수 있습니다. 이벤트 추적점을 설정하려면 중단점 탭에서 이벤트 추적점 추가 버튼을 클릭합니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 추적점

그러면 다음과 같은 이벤트 추적점 추가 팝업이 나타나는데, 이벤트 중단점과 동일하게 이벤트 드롭다운 박스에서 원하는 이벤트를 선택하고 추적 입력란에 출력할 메시지를 입력한 다음, 추가 버튼을 클릭하면 됩니다. 참고로 선택할 수 있는 이벤트의 종류는 이벤트 중단점의 경우와 동일합니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 추적점 추가 팝업

이번 예제에서는 추적할 구체적인 이벤트마우스 범주 하위의 click 이벤트를 선택하고, 추적 입력란에는 "Position X: " + event.clientX + ", Y: " + event.clientY 를 입력해서 마우스를 클릭한 좌표를 콘솔 창에 메시지로 출력해보도록 하겠습니다. 추가 버튼을 클릭합니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 추적점 추가 팝업

그러면 다음과 같이 작은 번개 표시가 추가된 빨간 마름모로 이벤트 추적점이 만들어집니다.

F12 개발자 도구 - 중단점 탭 - 이벤트 추적점

다시 버튼을 클릭해서 예제를 실행해보시기 바랍니다. 다음은 예제를 실행하고 콘솔 창을 살펴본 모습을 보여줍니다.

F12 개발자 도구 - 콘솔 탭 - 이벤트 추적점 결과

이미 살펴봤던 것처럼 이벤트 핸들러로 바인딩된 JavaScript 함수보다 이벤트 중단점/추적점이 호출되는 순서가 더 빠르기 때문에 이벤트 추적점의 메시지가 먼저 나타나게 됩니다.

XMLHttpRequest 중단점

마지막으로 중단점 탭에서 살펴볼 기능은 XMLHttpRequest 중단점입니다. 그러나 결론부터 말하자면 아쉽게도 이 기능은 IE11에서 정상적으로 동작하지 않습니다.

그 이름에서 미루어 짐작할 수 있는 것처럼 원래 의도대로라면 이 중단점을 설정할 경우 XHR 요청이 완료될 때마다, 즉 readyState 속성값이 4가 될 때마다 디버거 창에서 코드 실행이 중단되어야 합니다. 그렇지만 이미 언급한 바와 같이 정상적으로 동작하지 않을뿐만 아니라, 사용자의 환경에 따라서는 동일한 IE11을 사용하더라도 기능 자체가 제공되지 않습니다. 적어도 저는 이 기능이 정상적으로 동작하는 모습을 Edge에서조차 본 기억이 없습니다.

다음은 서비스 팩 1까지 설치된 영문 Windows 7 Enterprise 환경에서 IE11의 디버거 창을 살펴본 모습입니다. 우측 하단의 디버거 탭을 확인해보면 바로 잠시 뒤에 살펴볼 XMLHttpRequest 중단점 추가 버튼 자체가 제공되지 않는 것을 알 수 있습니다. 참고로 이 이미지는 Hyper-V를 이용해서 직접 캡처한 것입니다. 제가 아는 바가 정확하다면 이 기능은 Edge가 아직 '프로젝트 스파르탄'이라는 코드명으로 개발되던 시기에 추가된 기능입니다.

Windows 7 Enterprise - IE11 - 중단점 탭

다른 중단점이나 추적점을 설정할 때처럼 중단점 탭에서 XMLHttpRequest 중단점 추가 버튼을 클릭하면 XMLHttpRequest 중단점을 설정할 수 있습니다. 이 버튼을 클릭하면 다음과 같이 아래 위 화살표가 있는 빨간원으로 표시된 중단점이 바로 추가되며, 버튼을 몇 번을 누르더라도 단 한 개의 XMLHttpRequest 중단점만 추가됩니다. XMLHttpRequest 중단점에도 조건을 추가할 수는 있지만 기능 자체가 정상적으로 동작하지 않으므로 무의미하다고 판단되어 본문에서는 다루지 않습니다.

F12 개발자 도구 - 중단점 탭 - XMLHttpRequest 중단점

다음은 XMLHttpRequest 중단점을 살펴보기 위한 간단한 예제 HTML 파일입니다. 버튼을 클릭하면 제 개인 홈페이지의 특정 RSS 주소를 XHR로 요청한 다음, 응답 받은 결과를 console.dirxml() 함수로 출력합니다. 비교를 위해서 가장 기본적인 형태로 XHR 개체를 직접 사용하는 코드와 가장 일반적으로 사용되는 jQuery 라이브러리의 $.ajax() 메서드를 활용한 코드, 두 가지 방식을 모두 사용하고 있습니다. (새 창에서 보기)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>디버거 - XHR 기본 예제</title>
    <style>
      body {
        font-size: 12px;
        font-family: Tahoma;
      }
      input[type="button"] {
        display: block;
        width: 150px;
        height: 30px;
        margin: 5px;
      }
    </style>
  </head>
  <body>
    <input type="button" value="Test" onclick="fnAsync();" />

    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.js"></script>
    <script>
      function dirxml(xml) {
        console.dirxml(xml);
      }

      function fnAsync() {
        // Basic method.
        var objXHR = new XMLHttpRequest();
        objXHR.addEventListener("load", function() {
          dirxml(this.responseXML);
        });
        objXHR.open(
          "GET",
          "http://www.egocube.pe.kr/lecture/rss/html-javascript"
        );
        objXHR.send();

        // Using jQuery.
        $.ajax({
          url: "http://www.egocube.pe.kr/lecture/rss/html-javascript",
          dataType: "xml",
          cache: false
        }).done(function(data, textStatus, jqXHR) {
          dirxml(data);
        });
      }
    </script>
  </body>
</html>

이 예제를 직접 실행해보면 코드는 정상적으로 동작하지만 중단점은 전혀 반응하지 않습니다. 이는 Edge에서 테스트를 해봐도 마찬가지입니다. 다음은 예제를 실행하고 콘솔 창을 살펴본 모습입니다. 적어로 코드 자체는 아무런 문제 없이 동작하고 있음을 확인할 수 있습니다.

F12 개발자 도구 - 콘솔 탭 - XMLHttpRequest 중단점 결과

그리고 다음은 Chrome에서 동일한 테스트를 수행한 모습입니다. 의도한 바와 같이 모두 두 차례에 걸쳐서 정상적으로 중단점이 반응합니다. 다만 readyState 속성값이 4가 될 때가 아니라 send() 메서드가 호출되는 시점에 코드 실행이 중단된다는 점만 다를 뿐입니다. 사소한 부분이지만 웹 개발자들이 IE나 Edge보다 Chrome을 선호하는 근본적인 이유를 조금이나마 엿볼 수 있는 일면이라는 생각입니다.

F12 개발자 도구 - Chrome - XHR/fetch Breakpoints 테스트

IE11에서는 제공되지 않는 다른 중단점 기능들

Edge나 Chrome 같은 최신 브라우저에서는 지금까지 살펴본 IE11의 중단점이나 추적점 외에도 다음과 같은 기능들을 추가로 제공해줍니다. 각자 직접 테스트해 보시기 바랍니다.

호출 스택 탭

호출 스택은 JavaScript 엔진의 핵심적인 구성 요소 중 하나로, 현재 실행 중인 함수 및 메서드에 대한 정보를 저장하는 스택 형태의 자료 구조입니다. 디버깅 작업에서 호출 스택 탭이 중요한 이유는 함수나 메서드가 어떤 과정을 통해서 호출되었으며 다시 어떤 과정을 통해서 제어권을 반환하게 되는지를 파악할 수 있는 도구이기 때문입니다.

그러나 사실 F12 개발자 도구 디버거 창의 호출 스택 탭을 통해서 처리할 수 있는 작업은 그다지 많지가 않습니다. 기본적으로 JavaScript는 단일 스레드에서 실행되기 때문에 호출 스택도 하나만 존재하므로, C# 같은 언어를 디버깅할 때처럼 멀티 스레드에 따른 병렬 스택 같은 개념은 고려할 필요도 없고, 관련 기능은 거의 제공되지도 않기 때문입니다. (극히 일부 예외가 존재하는데 이에 대해서는 잠시 후에 살펴보도록 하겠습니다.) 그저 현재 실행 중인 함수나 메서드가 이러저러한 호출 과정을 거쳐서 실행되었다는 것을 확인하는 도구로만 사용해도 충분합니다.

다시 단어에 적절한 조사를 덧붙여주는 예제 HTML 파일로 되돌아가 보도록 하겠습니다. 이 예제에서는 my_library.js 파일 내부의 두 함수에서 jQuery 라이브러리가 제공하는 $.trim() 메서드를 사용합니다. 이 $.trim() 메서드의 정의 내부에 중단점을 설정하고 각각의 위치에서 코드 실행을 중단한 다음, 호출 스택 탭을 살펴보면 다음과 같습니다. 이 이미지는 비교하기 좋게 편집한 것입니다.

F12 개발자 도구 - 호출 스택 탭

이처럼 호출 스택 탭을 활용하면 동일한 $.trim() 메서드가 호출되었더라도 어떤 과정을 거쳐서 호출된 것인지 일목요연하게 파악할 수 있습니다. 만약 어떤 경우에는 함수나 메서드가 정상적으로 실행되고, 다른 경우에는 오류가 발생한다면 이 호출 스택 정보를 비교하여 호출 과정에 어떤 차이점이 존재하는지, 미처 감안하지 못한 요소가 있는지 문제의 원인을 찾는 수 밖에 없습니다. 참고로 목록의 가장 상단에 위치한 주황색 화살표로 표시된 함수가 현재 실행 중인 함수로, 호출 순서의 역순으로 표시됩니다.

이 상태에서 호출 스택 목록의 각 함수 항목을 마우스로 클릭하면 다음과 같이 조사식 탭에서 해당 함수의 관점에서 조사식 정보를 확인할 수 있습니다. 굳이 조사식 정보를 확인하기 위해서 해당 함수 또는 메서드로 다시 이동할 필요는 없습니다. 이렇게 현재 조사식 탭에 정보가 출력되는 함수는 녹색 화살표로 표시됩니다.

F12 개발자 도구 - 호출 스택 탭 - 조사식 탭 보기

또한 호출 스택 목록의 각 함수 항목을 마우스로 더블 클릭하면 해당 함수가 정의되어 있는 원본 소스의 줄로 바로 이동합니다. 만약 원본 소스 탭이 이미 열려 있다면 클릭만으로도 이동할 수 있습니다. 다음 글에서 살펴볼 라이브러리 코드에 관한 기능을 제외한다면 지금까지 살펴본 내용이 호출 스택 탭이 제공하는 기본적인 기능의 전부입니다.

멀티 스레드 스택 정보

이번 절을 시작하면서 F12 개발자 도구 디버거 창의 호출 스택 탭은 멀티 스레드에 관한 기능을 제공하지 않는다고 언급했던 것을 기억하실 것입니다. 그런데 가만히 생각해보면 과거 글에서 새 작업자에서 중단 버튼을 살펴보면서 웹 작업자 기술을 활용하여 JavaScript 코드를 메인 스레드 외의 별도의 스레드에서 실행하는 방법을 이미 알아봤었습니다. 호출 스택 탭은 이런 극히 예외적인 경우에 한하여 멀티 스레드 스택 정보를 제공해줍니다. 그러나 그렇다고 해서 별다른 기능을 제공해주는 것은 아니고 단지 호출 스택 목록을 요약하여 보여주는 수준에 불과합니다.

다음은 새 작업자에서 중단 버튼예제를 디버거에서 중단하고 호출 스택 탭을 살펴본 모습입니다. 지금까지와는 달리 주 스레드 범주 외에 Worker#1이라는 별도의 스레드 범주가 제공되는 것을 확인할 수 있습니다.

F12 개발자 도구 - 호출 스택 탭 - 웹 작업자

그리고 제어권이 웹 작업자의 함수나 메서드로 넘어가면 다음과 같이 해당 스레드의 호출 스택 목록이 제공됩니다.

F12 개발자 도구 - 호출 스택 탭 - 웹 작업자

비동기 스택 정보

웹 작업자 스레드의 경우 말고도 주 스레드 외의 범주를 요약하여 보여주는 경우가 한 가지 더 존재합니다. 바로 비동기 호출에 대한 호출 스택 정보을 살펴보는 경우입니다. 가령 이번에는 XMLHttpRequest 중단점 절의 예제에서 dirxml() 함수 정의 내부에 중단점을 설정하고 코드 실행을 중단한 다음, 호출 스택 탭을 살펴보겠습니다. 이 예제에서는 XHR 호출이 두 차례 이루어지므로 두 경우를 비교하기 좋게 편집하면 다음과 같습니다.

F12 개발자 도구 - 호출 스택 탭 - 비동기 호출

좌측이 가장 기본적인 형태로 XHR 개체를 직접 사용한 경우의 호출 스택이고, 우측이 jQuery 라이브러리의 $.ajax() 메서드를 사용한 경우의 호출 스택입니다. 이 경우 주 스레드 범주 하위의 각 함수 항목을 마우스로 클릭하면 앞에서 살펴봤던 것처럼 해당 함수의 관점에서 조사식 정보를 확인할 수 있지만, 비동기 호출 범주 하위의 항목들은 클릭하더라도 조사식 탭에 아무런 변화도 일어나지 않습니다.

이와 관련해서 호출 스택 탭의 우측 상단에 비동기 프레임 표시하기/숨기기 버튼도 제공되지만, 단지 비동기 호출 범주 하위의 노드들을 접거나 펼치는 기능일 뿐입니다.

F12 개발자 도구 - 호출 스택 탭 - 비동기 프레임 표시하기/숨기기 버튼

정리

본문에서는 아직 살펴보지 못한 F12 개발자 도구 디버거 창의 기증들 중에서 중단점 탭과 호출 스택 탭이 제공해주는 기능들을 조금 더 자세하게 살펴봤습니다.

다음 글에서는 몇 가지 남아있는 디버거 창의 나머지 유용한 기능들을 마저 살펴보고 디버거 창에 대한 내용을 마무리 짓도록 하겠습니다.