ホームページ > ウェブフロントエンド > jsチュートリアル > Web アプリの JavaScript デバッグをマスターする方法

Web アプリの JavaScript デバッグをマスターする方法

Linda Hamilton
リリース: 2025-01-17 02:32:10
オリジナル
117 人が閲覧しました

アイビー・ワロブワ著✏️

Web アプリが複雑になるにつれて、デバッグの技術を習得することが不可欠になります。

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 ファイルを追加します。モードを実稼働に設定すると、webpack に変更などの最適化を適用するよう指示します:

 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;
ログイン後にコピー

ボタンをクリックすると、現在、テーブル上の以前のカウント、現在のカウント、および合計が更新されます。前回のカウントは以前のカウント値を返し、合計カウントはすべてのカウント値の合計を返すことになっています。現時点では、前のカウントには現在のカウントが表示されますが、合計カウントは 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 行目に 2 つのブレークポイントが追加されています。これらのブレークポイントはパネルから有効または無効にできます
  • スコープ パネル — 現在のブレークポイントでの変数の状態と値を検査するために重要です
  • デバッグ コントロール これにより、コードをステップごとにナビゲートできます。コントロールは次のとおりです: 再開、ステップオーバー、ステップイン、ステップアウト、ステップ

これにより、アプリをさらにデバッグできるようになります。

3. スコープパネル

スコープ パネルは、元のソースからの変数を確認できるため、JavaScript のデバッグに効果的です。

scope panel javascript debugging

次のスコープ変数が表示されます:

  1. ローカル - これらは、現在実行中の関数内で定義された変数です
  2. クロージャ - これらの変数は、実行関数の外側のブロックまたはスクリプト スコープからキャプチャされます
  3. クロージャ - このタイプの変数は、モジュール ファイルなどを使用して生成されたスコープから取得されます
  4. グローバル - これらはアプリケーション全体で使用できる変数です

スコープ パネルとログ ポイント ブレークポイントから、現在のカウントが 1 であるのに対し、増加前のカウントは 0 であることがわかります。したがって、増分前のカウントを前のカウントとして保存する必要があります。

4. コードのステップ実行 (_s_tep into、ステップオーバー、ステップアウト)

コードをステップ実行するには、JavaScript のデバッグ中にさまざまな方法でプログラム内を移動する必要があります。

  • ステップイン - 関数呼び出しに入り、その関数内のコードを調べることができます
  • ステップオーバー - 関数呼び出しをスキップし、実行せずに実行します
  • ステップアウト - 関数にステップインした場合に、関数の呼び出し元コンテキストに戻ることができます

デバッグ コントロールを使用してコードをステップ実行できます。 Step コントロールを使用すると、コードを一度に 1 行ずつ実行できます。 ステップ をクリックすると、6 行目が実行され、7 行目に移動します。スコープ内でpreviousCountの値がどのように変化するかに注目してください:

stepping through code

ステップオーバー コントロールを使用すると、1 行ずつ実行することなく関数を実行できます。

stepping over code

ステップイン コントロールを使用すると、関数に入ることができます。関数では、コードを 1 行ずつステップ実行するか、以下に示すように関数から ステップアウト することができます。関数からステップアウトすると、残りの行の実行が終了します:

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 行目を実行するときに、3 つの関数呼び出しが行われます。スタック内の関数のフローを観察するには、以下に示すように Restart Frame を使用して関数の実行を再開できます。

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 DevTools を使用した React アプリのデバッグに関するこの記事など、Web アプリのデバッグに関する追加リソースを探索できます。これにより、React ベースのアプリケーションのデバッグに関する貴重な洞察が得られます。さらに、Chrome DevTools を使用した Node.js のデバッグに関するこのガイドでは、ウォッチャーやその他の高度な DevTools 機能を使用してサーバーサイド JavaScript をデバッグするためのヒントを提供します。これらのリソースは、ここで説明した手法を補完し、Web アプリのデバッグについての理解を広げることができます。

結論

このチュートリアルでは、ソース マップと Chrome DevTools を使用した縮小コードのデバッグについて説明しました。ソース マップを生成することで、縮小されたコードを元のソースにマップし直し、Web アプリのデバッグを容易にしました。 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 プラグイン

今すぐ始めましょう。

以上がWeb アプリの JavaScript デバッグをマスターする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート