> 웹 프론트엔드 > JS 튜토리얼 > 웹 앱용 JavaScript 디버깅을 마스터하는 방법

웹 앱용 JavaScript 디버깅을 마스터하는 방법

Linda Hamilton
풀어 주다: 2025-01-17 02:32:10
원래의
114명이 탐색했습니다.

작사: Ivy Walobwa✏️

웹 앱이 복잡해짐에 따라 디버깅 기술을 익히는 것이 필수적입니다.

효과적인 JavaScript 디버깅에는 단순히 오류를 수정하는 것 이상이 포함됩니다. 앱이 원활하게 실행되고 최상의 사용자 경험을 제공하려면 코드가 내부적으로 어떻게 작동하는지 이해해야 합니다.

프로덕션 사용자에게 전달되는 코드 버전인 축소된 코드는 성능에 최적화되어 있습니다. 그러나 축소된 코드는 디버깅하기에 악몽이 될 수 있습니다. 사용자에게 오류가 발생하면 축소된 코드로 문제를 재현하고 진단하는 것이 어려운 경우가 많습니다.

그러나 올바른 도구를 사용하면 JavaScript 디버깅이 훨씬 쉬워질 수 있습니다. 이 문서에서는 소스 맵을 활용하여 축소된 코드를 디버깅하고 Chrome DevTools를 사용하여 웹 앱의 문제를 효율적으로 식별하고 해결하는 다른 기술을 살펴보는 방법을 살펴봅니다.

예시 앱

카운트를 증가시키고 이를 콘솔에 기록하는 간단한 앱을 개발해 보겠습니다. 이 앱은 축소된 코드로 인해 디버깅이 어떻게 까다로워지고 소스 맵이 프로세스를 단순화하는 데 어떻게 도움이 되는지 보여줍니다.

아래에서 .js 파일을 만들고 다음과 같이 코드 조각을 추가하세요.

1. src/counterCache.js

export const countCache = { 
     previousCount: 0, 
     currentCount: 0, 
     totalCount: 0 
}
export function updateCache(currentCount, previousCount) { 
     countCache.currentCount = currentCount; 
     countCache.previousCount = previousCount; c
     ountCache.totalCount = countCache.totalCount + countCache.currentCount; 
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

2.src/counter.js:

import { updateCache } from './counterCache.js';
let count = 0; 
export function incrementCounter() 
     { count += 1; 
     const previousCount = count; 
     updateCache(count, previousCount); 
}
로그인 후 복사
로그인 후 복사

3.src/index.js:

import { incrementCounter } from './counter';
import { countCache } from './counterCache';
const button = document.createElement('button');
const previousElement = document.getElementById('previous');
const currentElement = document.getElementById('current');
const totalElement = document.getElementById('total');
button.innerText = 'Click me';
document.body.appendChild(button);
button.addEventListener('click', () => {
     incrementCounter();
     previousElement.innerText = countCache.previousCount;
     currentElement.innerText = countCache.currentCount;
     totalElement.innerText = countCache.total();
});
로그인 후 복사
로그인 후 복사

package.json 파일에 아래와 같이 webpack 패키지를 추가한 후 npm i를 실행하여 설치하세요. 프로덕션용 축소 코드를 생성하기 위해 빌드 프로세스의 일부로 webpack을 사용할 것입니다.

  "devDependencies": {
    "webpack": "^5.96.1",
    "webpack-cli": "^5.1.4"
  }
로그인 후 복사

코드 축소를 활성화하려면 다음 스니펫을 사용하여 webpack.config.js 파일을 추가하세요. 모드를 프로덕션으로 설정하면 웹팩이 수정과 같은 최적화를 적용하도록 지시합니다.

 const path = require('path');
    module.exports = {
        mode: 'production', // Enables optimizations like minification and tree-shaking
        entry: './src/index.js', // Specifies the entry point of your application
        output: {
            path: path.resolve(__dirname, 'dist'),// Defines the output directory for bundled files
            filename: 'bundle.js',// Specifies the name of the bundled file
        },
    };
로그인 후 복사

이제 npx webpack을 실행하여 코드를 묶고 축소하세요. dist/bundle.js 파일은 아래와 같은 내용으로 생성됩니다. 축소는 변수 및 함수 이름을 모호하게 하고 공백, 주석, 사용되지 않는 코드와 같은 불필요한 문자를 제거하여 출력 파일을 더 작고 더 빠르게 로드합니다.

(()=>{"use strict";const t={};let e=0;const n=document.createElement("button"),o=document.getElementById("previous"),u=document.getElementById("current"),r=document.getElementById("total");n.innerText="Click me",document.body.appendChild(n),n.addEventListener("click",(()=>{var n,c;e+=1,n=e,c=e,t.currentCount=n,t.previousCount=c,t.totalCount=t.totalCount||0+t.currentCount,o.innerText=t.previousCount,u.innerText=t.currentCount,r.innerText=t.total()}))})();
로그인 후 복사

다음으로, 번들 출력을 참조하도록 index.html 파일을 업데이트하여 애플리케이션이 축소된 코드를 사용하는지 확인하세요.

<<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Debugging Example</title>
    <link rel="stylesheet" href="styles.css"> 
</head>
<body>
    <h1>Web Debug App</h1>
    <p>Check console for bug</p>
    <table>
        <thead>
            <tr>
                <th>Previous count</th>
                <th>Current count</th>
                <th>Total count</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>



<p>Finally, run the app and check the console after clicking the button. To preview the app locally, you can use the Live Server extension in VS Code:</p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173705233279872.png" alt="app error using minified code" loading="lazy"    style="max-width:90%"  style="max-width:90%"></p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173705233320770.png" alt="Bundled source file" loading="lazy"    style="max-width:90%"  style="max-width:90%"></p>

<p>The error in the console, t.total is not a function, is difficult to interpret. Clicking on the file in the console does not help pinpoint the issue due to the compact and obfuscated nature of minified code. Identifying the root cause of such an error in a large codebase can be frustrating and time-consuming, as the minified code obscures the original logic and context.</p>

<h2>
  
  
  8 JavaScript debugging strategies for web apps
</h2>

<p>Let’s demonstrate eight methods to help make JavaScript debugging a bit easier:</p>

<h3>
  
  
  1. Source maps
</h3>

<p>Source maps are files that map your minified code back to the original source code. They make debugging easier and help investigate issues in production. The file names of source maps end with .map.</p>

<p>To generate source maps using webpack, update the webpack.config.js file as follows:</p>

<p>The devtool: 'source-map' or devtool: 'eval-source-map' line tells webpack to generate an external .map file which maps the minified code back to your original source code. The source map file URL is also added to the minified code in the bundle.js file.</p>

<p>Now run npx webpack. The .map file will generate alongside your minified bundle. Serve the application using a local server, and open it in an Incognito browser window. This prevents browser extensions and cached files from interfering with your debugging process.</p>

<p>With source maps generated, the following observations are made:</p>

<ol>
<li> The error is linked to the counter.js file, which is the original source code</li>
<li> The source map, bundle.js.map is successfully fetched and is visible under the <strong>Developer resources</strong> tab</li>
<li> In the <strong>Sources</strong> tab, the developer tools display the original source code and the problematic line</li>
</ol>

<p>The exact code and file causing the bug are easy to identify using source maps:</p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173705233514189.png" alt="app error from source maps" loading="lazy"    style="max-width:90%"  style="max-width:90%"></p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173705233621716.png" alt="mapped source code javascript debugging" loading="lazy"    style="max-width:90%"  style="max-width:90%"></p>

<p>With the clear error above, we are able to fix the error and access the correct property on countCache.</p>

<p>Our guide on how to use Chrome DevTools should provide a great start. To open the <strong>Developer resources</strong> tab, click on the <strong>More</strong> icon, then <strong>More tools</strong> then <strong>Developer resources</strong>. This tab allows you to view the source map load status and even load source maps manually:</p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173705233875017.png" alt="accessing developer resources tab javascript debugging" loading="lazy"    style="max-width:90%"  style="max-width:90%"></p>

<p>The code snippet below fixes the bug on the console. Update your code, then run npx webpack to compile the changes. Once completed, serve the application and view the updated output in the table:<br>
</p>

<pre class="brush:php;toolbar:false">totalElement.innerText = countCache.totalCount;
로그인 후 복사

현재 버튼을 클릭하면 테이블의 이전 개수, 현재 개수, 합계가 업데이트됩니다. 이전 count는 count의 이전 값을 반환하고 총 count는 모든 count 값의 합계를 반환합니다. 현재는 이전 카운트가 현재 카운트를 표시하고 전체 카운트가 1에 멈춘 상태입니다.

다음 섹션에서는 이 문제를 식별하고 해결하기 위해 중단점 사용 및 코드 단계별 실행과 같은 추가 JavaScript 디버깅 기술을 살펴보겠습니다.

web debugging example app output

2. 중단점

중단점을 사용하면 특정 줄에서 코드 실행을 일시 중지하여 변수를 검사하고 표현식을 평가하고 코드 흐름을 이해하는 데 도움이 됩니다. 목표에 따라 사용할 수 있는 다양한 중단점이 있습니다. 예를 들면 다음과 같습니다.

  • 코드 줄 — 지정된 정확한 줄에서 코드 실행을 일시 중지합니다
  • 조건부 코드 줄 — 지정된 조건이 true인 경우에만 실행을 일시 중지합니다
  • 로그 포인트 —코드 실행을 일시 중지하지 않고 대신 해당 코드 줄이 실행될 때 콘솔에 사용자 지정 메시지를 기록합니다

샘플 애플리케이션에서는 incrementCounter 함수에 중단점을 적용합니다. Sources 패널에서 counter.js 파일을 열고 6번째 줄 왼쪽을 클릭하세요. 이는 개수가 증가한 후 코드 줄 중단점을 설정합니다.

setting line of code breakpoint

5번째 줄에 또 다른 중단점을 설정하고 편집하겠습니다. 중단점을 편집하려면 강조 표시된 섹션을 마우스 오른쪽 버튼으로 클릭한 다음 중단점 편집을 클릭합니다.

edit breakpoint javascript debugging

중단점 유형을 로그 지점으로 설정한 다음 콘솔에 기록할 메시지를 입력합니다.

setting logpoint breakpoint

버튼을 클릭하면 애플리케이션이 코드 줄 중단점에서 일시 중지되고 로그 포인트 세트에서 콘솔에 디버그 로그가 인쇄됩니다.

app paused line of code breakpoint

이미지에서 다음 섹션을 볼 수 있습니다.

  • 중단점 패널 — 중단점을 관리하고 전환하는 데 도움이 됩니다. 현재 5행과 6행에 두 개의 중단점이 추가되었습니다. 이러한 중단점은 패널에서 활성화하거나 비활성화할 수 있습니다
  • 범위 패널 — 현재 중단점에서 변수 상태와 값을 검사하는 데 중요
  • 디버깅 컨트롤 이를 통해 코드를 단계별로 탐색할 수 있습니다. 컨트롤은 다음과 같습니다: 재개, 한 단계 더 나아가기, 한 단계 더 나아가기, 한 단계 더 나아가기 및 단계

이를 통해 앱을 추가로 디버그할 수 있습니다.

3. 범위 패널

범위 패널을 사용하면 원본 소스의 변수를 볼 수 있으므로 JavaScript 디버깅에 효과적일 수 있습니다.

scope panel javascript debugging

다음 범위 변수를 볼 수 있습니다.

  1. 로컬 - 현재 실행 중인 함수 내에서 정의된 변수입니다
  2. 클로저 - 이 변수는 실행 함수의 외부 블록 또는 스크립트 범위에서 캡처됩니다
  3. 클로저 - 이 유형의 변수는 모듈 파일을 사용하여 생성된 범위에서 가져옵니다
  4. 전역 - 애플리케이션 전체에서 사용할 수 있는 변수입니다

범위 패널과 로그 지점 중단점을 보면 현재 개수가 1이고 증가 전 개수가 0임을 확인할 수 있습니다. 따라서 증가 전의 개수를 이전 개수로 저장해야 합니다.

4. 코드 단계별 실행(_s_tep into, step over, step out)

코드를 단계별로 실행하려면 JavaScript 디버깅 중에 다양한 방식으로 프로그램을 탐색해야 합니다.

  • 한 단계씩 실행 - 함수 호출에 들어가 해당 함수 내부의 코드를 검사할 수 있습니다
  • 스텝 오버 - 함수 호출을 건너뛰고 다이빙하지 않고 실행
  • Step out - 함수에 들어간 경우 함수의 호출자 컨텍스트로 돌아갈 수 있습니다

디버그 컨트롤을 사용하여 코드를 단계별로 실행할 수 있습니다. Step 컨트롤을 사용하면 한 번에 한 줄씩 코드를 실행할 수 있습니다. Step을 클릭하면 6번째 줄이 실행되고 7번째 줄로 이동합니다. 범위에서 PreviousCount 값이 어떻게 변경되는지 확인하세요.

stepping through code

Step over 컨트롤을 사용하면 한 줄씩 실행하지 않고도 기능을 실행할 수 있습니다.

stepping over code

한 단계씩 컨트롤을 사용하면 기능으로 이동할 수 있습니다. 함수에서는 아래와 같이 코드를 한 줄씩 실행하거나 Step Out할 수 있습니다. 함수에서 나가면 나머지 줄의 실행이 완료됩니다.

step into and step out of a line of code

문제를 해결하기 위해 아래와 같이 코드를 업데이트하겠습니다. 이제 테이블의 이전 개수가 올바르게 표시됩니다.

export const countCache = { 
     previousCount: 0, 
     currentCount: 0, 
     totalCount: 0 
}
export function updateCache(currentCount, previousCount) { 
     countCache.currentCount = currentCount; 
     countCache.previousCount = previousCount; c
     ountCache.totalCount = countCache.totalCount + countCache.currentCount; 
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

5. 호출 스택

호출 스택은 코드의 현재 지점으로 이어지는 일련의 함수 호출을 보여줍니다.

표시된 대로 counterCache.js 파일에 새 중단점을 추가한 다음 버튼을 클릭합니다. 호출 스택 패널을 살펴보세요.

call stack panel

앱이 counterCache.js의 6번째 줄을 실행할 때 세 가지 함수 호출이 발생합니다. 스택에 있는 함수의 흐름을 관찰하려면 아래와 같이 프레임 다시 시작을 사용하여 실행을 다시 시작할 수 있습니다.

restart frame call stack

6. 스크립트 무시

디버깅할 때 작업 흐름 중에 특정 스크립트를 무시할 수 있습니다. 이는 라이브러리나 코드 생성기에서 코드의 복잡성을 건너뛰는 데 도움이 됩니다. 우리의 경우 디버깅하는 동안 counter.js 스크립트를 무시하려고 합니다.

페이지 탭에서 무시할 파일을 마우스 오른쪽 버튼으로 클릭하고 무시 목록에 스크립트를 추가합니다.

add script ignore list

앱을 실행하고 중단점에서 일시 중지하면 이제 호출 스택에서 incrementCounter 함수가 무시되는 것을 볼 수 있습니다. 무시된 프레임을 숨기거나 표시할 수 있습니다:

ignored frames call stack

페이지 탭에서 파일을 그룹화하면 아래 이미지와 같이 더 쉽게 탐색할 수 있습니다.

grouping source files

7. 시계 표현식

감시 표현식을 사용하면 코드가 실행될 때 특정 변수나 표현식을 추적하여 변경 사항을 실시간으로 모니터링할 수 있습니다. countCache와 같은 표현식을 추가하여 코드를 단계별로 진행하면서 값을 모니터링할 수 있습니다.

adding watch expressions

8. 코드 조각 디버깅

총 개수와 관련된 버그를 수정하려면 콘솔에서 코드 조각을 실행하여 논리적 오류를 이해할 수 있습니다. 콘솔에서 반복적으로 실행하는 코드를 디버깅할 때 스니펫을 활용할 수 있습니다.

스니펫 탭에서 샘플 디버그 스크립트를 추가하고 스크립트를 저장한 다음 Enter를 클릭하여 스크립트를 실행합니다.

javascript debugging snippet

문제를 해결하려면 버그가 포함된 표현을 다시 정렬해야 한다는 것을 알 수 있습니다.

export const countCache = { 
     previousCount: 0, 
     currentCount: 0, 
     totalCount: 0 
}
export function updateCache(currentCount, previousCount) { 
     countCache.currentCount = currentCount; 
     countCache.previousCount = previousCount; c
     ountCache.totalCount = countCache.totalCount + countCache.currentCount; 
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

React 기반 애플리케이션 디버깅에 대한 귀중한 통찰력을 제공하는 React DevTools를 사용한 React 앱 디버깅에 대한 이 문서와 같이 웹 앱 디버깅에 대한 추가 리소스를 탐색할 수 있습니다. 또한 Chrome DevTools를 사용하여 Node.js를 디버깅하는 방법에 대한 이 가이드에서는 감시자 및 기타 고급 DevTools 기능을 사용하여 서버 측 JavaScript를 디버깅하기 위한 팁을 제공합니다. 이러한 리소스는 여기에 설명된 기술을 보완하고 웹 앱 디버깅에 대한 이해를 넓힐 수 있습니다.

결론

이 튜토리얼에서는 축소된 코드 버스싱 소스 맵과 Chrome DevTools 디버깅을 살펴보았습니다. 소스 맵을 생성하여 축소된 코드를 원래 소스에 다시 매핑하여 웹 앱을 더 쉽게 디버그할 수 있게 했습니다. Chrome DevTools는 중단점, 코드 단계별 실행, 표현식 보기 등과 같은 방법을 통해 JavaScript 디버깅 프로세스를 더욱 향상시켰습니다.

이러한 도구를 사용하면 개발자는 복잡하고 축소된 코드베이스를 처리할 때에도 애플리케이션을 효율적으로 디버깅하고 최적화할 수 있습니다. 이 프로젝트의 전체 코드는 GitHub에서 찾을 수 있습니다.


몇 분 만에 LogRocket의 최신 오류 추적을 설정하세요.

  1. https://logrocket.com/signup/을 방문하여 앱 ID를 받으세요.
  2. NPM 또는 스크립트 태그를 통해 LogRocket을 설치합니다. LogRocket.init()는 서버측이 아닌 클라이언트측에서 호출해야 합니다.

NPM:

import { updateCache } from './counterCache.js';
let count = 0; 
export function incrementCounter() 
     { count += 1; 
     const previousCount = count; 
     updateCache(count, previousCount); 
}
로그인 후 복사
로그인 후 복사

스크립트 태그:

import { incrementCounter } from './counter';
import { countCache } from './counterCache';
const button = document.createElement('button');
const previousElement = document.getElementById('previous');
const currentElement = document.getElementById('current');
const totalElement = document.getElementById('total');
button.innerText = 'Click me';
document.body.appendChild(button);
button.addEventListener('click', () => {
     incrementCounter();
     previousElement.innerText = countCache.previousCount;
     currentElement.innerText = countCache.currentCount;
     totalElement.innerText = countCache.total();
});
로그인 후 복사
로그인 후 복사

3.(선택 사항) 스택과의 심층 통합을 위해 플러그인을 설치합니다.

  • Redux 미들웨어
  • ngrx 미들웨어
  • Vuex 플러그인

지금 시작하세요.

위 내용은 웹 앱용 JavaScript 디버깅을 마스터하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿