[기초]JavaScript 디버깅: 문제를 해결하는 순서와 팁

JIIJIIJ·2025년 1월 7일
0

JavaScript

목록 보기
21/23
post-thumbnail

JavaScript 디버깅: 아주 기본

개발을 하다 보면 코드가 예상대로 작동하지 않는 경우가 많다.
특히 JavaScript처럼 동적인 언어는 비동기 처리, 브라우저 환경, 다양한 라이브러리와의 호환성 등으로 인해 디버깅이 까다로울 수(귀찮을 수..) 있다.

이 글에서는 JavaScript 디버깅을 체계적으로 수행할 수 있는 방법(아주 기본)을 공유한다.


1. 첫 단계: 문제 정의

문제가 생겼을 때 “무엇이 잘못되었는지”를 명확히 정의하는 것이 가장 중요하다.
여기서 문제 정의란, 에러 메시지나 비정상적인 동작을 관찰하고 이를 구체적으로 기술하는 것을 의미한다.

예시

  • 화면이 하얗게 멈추고 아무것도 나타나지 않을 때
  • 콘솔에 Uncaught TypeError: undefined is not a function 등의 에러 메시지가 출력될 때
  • 이벤트가 예상대로 작동하지 않을 때

문제를 정의할 때 체크리스트

  • 브라우저의 콘솔(Console)을 열어 에러 메시지를 확인한다.
  • 문제를 재현할 수 있는 조건을 명확히 한다.
    • 어떤 버튼을 눌렀을 때 발생하는지?
    • 특정 데이터가 입력될 때만 오류가 나는지?

2. 디버깅 시작: 브라우저 개발자 도구 활용

JavaScript 디버깅에서 브라우저 개발자 도구(DevTools)는 기본 중의 기본이다.
Chrome 기준으로 설명한다.

DevTools 주요 탭 소개

  • Console 탭

    • console.log()로 변수 값, 함수 흐름을 출력
    • 에러 메시지 및 경고를 실시간 확인
  • Source 탭

    • 중단점(Breakpoint) 설정으로 코드 실행 흐름 정지 가능
    • 변수 값, 호출 스택, 실행 흐름을 상세히 분석
    • 함수 호출 전 중단점을 설정해 한 단계씩 호출스택 흐름을 추적
  • Network 탭

    • AJAX 요청, API 응답 상태, 응답 데이터 확인
    • 네트워크 요청 실패 여부 및 이유 파악

3. 로그 출력으로 문제 확인하기

너무 당연하지만, 기초부터 정리하기 위해 적는다.

function fetchData(url) {
    console.log("Fetching data from:", url); // 요청 URL 확인
    fetch(url)
        .then(response => response.json())
        .then(data => {
            console.log("Received data:", data); // 받은 데이터 출력
        })
        .catch(error => {
            console.error("Error occurred:", error); // 오류 로그 출력
        });
}
fetchData("/api/data");

4. 코드 재현을 통한 문제 단순화

복잡한 코드는 디버깅을 어렵게 만든다.
문제가 발생하는 코드만 따로 재현해서 원인을 좁혀가는 것도 좋은 방법이다.

개인적으로는 Cafe24 등에서 테스트용 페이지를 만들어 실험하기도 한다.

예시: 입력 값 검증

function calculatePrice(basePrice, discount) {
    console.log("Inputs:", { basePrice, discount }); // 입력 확인
    if (typeof basePrice !== "number" || typeof discount !== "number") {
        console.error("Invalid input types");
        return null;
    }
    return basePrice - discount;
}

calculatePrice(100, "10%"); // 잘못된 입력으로 테스트

5. 비동기 코드 디버깅

JavaScript의 비동기 코드는 오류 추적을 어렵게 만든다.
Promise와 async/await에 대한 이해가 필수며, 적절한 에러 처리가 필요하다.

Promise 디버깅

fetch("/api/data")
    .then(response => response.json())
    .then(data => {
        console.log("Data received:", data);
    })
    .catch(error => {
        console.error("Error fetching data:", error);
    });

async/await 디버깅

async function getData() {
    try {
        const response = await fetch("/api/data");
        const data = await response.json();
        console.log("Data received:", data);
    } catch (error) {
        console.error("Error occurred:", error);
    }
}
getData();

6. 디버깅 도구 및 라이브러리 활용

고급 디버깅 도구를 사용하면 문제 해결 속도를 높일 수 있다.
대규모 프로젝트, 상태 관리 등에서 특히 유용하다.

추천 도구

  • React Developer Tools
    React 컴포넌트의 상태와 Props 실시간 추적

  • Redux DevTools
    Redux 상태 변화, 액션을 시각적으로 확인 가능

  • Lighthouse
    웹 페이지의 성능, 접근성, SEO 진단


마무리

JavaScript 디버깅은 단순히 오류를 찾는 것 이상의 과정이다.
코드의 동작 방식을 깊이 이해하고 개선하는 기회가 될 수 있다.

실제로 디버깅을 하면서 실행 컨텍스트, JavaScript 동작 원리 등을 더 잘 이해하게 되었다.
LLM을 활용해 “에러 나는데 해결해줘!”라고 물어보는 것도 좋지만, 콘솔 로그브라우저 디버거를 잘 활용하고, 문제가 발생하는 부분만 단순화해 재현하고, 비동기 코드 흐름에 대한 이해를 바탕으로 디버깅을 체계적으로 정리하는 습관이 개발자 성장에 필수라고 생각한다.

profile
다크모드가 보기 좋아요

0개의 댓글