Chrome DevTools で JavaScript をデバッグする

このインタラクティブなチュートリアルでは、Chrome DevTools で JavaScript をデバッグするための基本的なワークフローを順を追って説明します。 このチュートリアルでは、1 つの特定の問題をデバッグする方法について説明しますが、この一般的なワークフローは、あらゆるタイプの JavaScript のバグをデバッグするのに役立ちます。

console.log() を使用してコードのバグを探し、修正している方は、このチュートリアルで概要を説明しているワークフローの採用を検討してください。 多くの場合、このワークフローの方が速く効率的です。

ステップ 1: バグを再現する

デバッグを始めるには、必ず最初にバグを再現する必要があります。「バグを再現する」とは、バグを一貫して発生させる一連のアクションを特定することです。 バグを何度も発生させる必要がある場合もあるため、不要なステップは排除してください。

以下の手順に従って、このチュートリアルで修正するバグを再現します。

  1. 以下の[デモを開く] をクリックして、新しいタブでデモを開きます。

  2. デモで、[Number 1] に 5 を入力します。

  3. [Number 2] に 1 を入力します。
  4. [Add Number 1 and Number 2] をクリックします。
  5. 入力ボタンの下のラベルを確認してください。5 + 1 = 51 と表示されています。

この結果は間違いです。結果は 6 になる必要があります。このバグを、これから修正します。

ステップ 2: ブレークポイントでコードを一時停止する

DevTools を使用すると、コードの実行中にコードを一時停止し、その時点におけるすべての変数の値を調べることができます。 コードを一時停止するためのツールは、ブレークポイントと呼ばれます。 さっそく試してみましょう。

  1. Command+Option+I キー(Mac)または Control+Shift+I キー(Windows、Linux)を押して、デモで DevTools を開きます。

  2. [Sources] タブをクリックします。

  1. [Event Listener Breakpoints] をクリックして、セクションを展開します。DevTools に、[Animation] や [Clipboard] などの展開可能なイベント カテゴリのリストが表示されます。
  1. [Mouse] イベント カテゴリの横にある [Expand] 展開アイコン をクリックします。

DevTools に、[click] など、チェックボックスが横にあるマウスイベントのリストが表示されます。 1. [click] チェックボックスをオンにします。

 <figure>
   <img src="imgs/get-started-click-breakpoint.png"
     alt="DevTools opened on the demo, with the Sources panel in focus
          and click event listener breakpoints enabled."
   <figcaption>
     <b>図 1</b>: デモで開かれた DevTools。[Sources] パネルが表示されており、クリック イベント リスナのブレークポイントが有効になっています。

     DevTools ウィンドウが大きい場合、[<b>Event Listener Breakpoints</b>] ペインは左下ではなく、スクリーンショットのように右側に表示されます。</figcaption>
 </figure>
  1. デモに戻り、[Add Number 1 and Number 2] を再度押します。DevTools はデモを一時停止し、[Sources] パネルでコード行をハイライト表示します。DevTools では次のコード行がハイライト表示されています。

    function onClick() {

[click] チェックボックスをオンにすると、すべての click イベントにイベントベースのブレークポイントが設定されます。 任意のノードがクリックされたときに、そのノードに click ハンドラがあると、DevTools はそのノードの click ハンドラの最初の行で自動的に一時停止します。

注: このブレークポイントは、DevTools で提供される多様なブレークポイントの 1 つです。デバッグする問題のタイプに応じて、異なるブレークポイントを使用する必要があります。

ステップ 3: コードをステップ実行する

バグの一般的な原因の 1 つは、スクリプトの実行順序が間違っていることです。 コードをステップ実行すると、コードを 1 行ずつ実行して、予想とは異なる順序で実行されているコード行を見つけることができます。 さっそく試してみましょう。

  1. DevTools の [Sources] パネルで、[Step into next function call] Step into next function call をクリックし、onClick() 関数を 1 行ずつステップ実行します。

DevTools では次のコード行がハイライト表示されます。

   `if (inputsAreEmpty()) {`
  1. [Step over next function call] Step over next function call をクリックします。 DevTools は、ステップ実行せずに、inputsAreEmpty() を実行します。DevTools が数行のコードをスキップしていることに注意してください。これは、inputsAreEmpty() が false と評価されたため、if 文のコードブロックが実行されなかったからです。

以上がコードをステップ実行する際の基本的な考え方です。get-started.js 内のコードを調べると、updateLabel() 関数のどこかにバグがあることがわかります。 コードの各行をステップ実行する代わりに、別のタイプのブレークポイントを使用すると、バグがある箇所の付近でコードを一時停止することができます。

ステップ 4: 別のブレークポイントを設定する

コード行のブレークポイントは、最も一般的なタイプのブレークポイントです。特定のコード行で一時停止したい場合は、コード行のブレークポイントを使用します。 さっそく試してみましょう。

  1. updateLabel() の最後のコード行には、次のようなコードがあります。

    label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;

  2. コードの左側には、この特定のコードの行番号 32 が表示されています。 32 をクリックします。DevTools により、32 の上に青いアイコンが配置されます。 このアイコンは、この行にコード行のブレークポイントがあることを示します。 これで、DevTools は、このコード行が実行される前に常に一時停止します。

  3. [Resume script execution] Resume script execution をクリックします。 スクリプトは、ブレークポイントを設定したコード行に到達するまで実行されます。
  4. 既に実行された updateLabel() のコード行を確認します。DevTools で、addend1addend2、および sum の値が出力されています。

sum の値に問題がありそうです。この値は、数字である必要がありますが、文字列として評価されているようです。 これがバグの原因であると考えられます。

ステップ 5: 変数値をチェックする

バグのもう 1 つの一般的な原因は、変数または関数が予想とは異なる値を生成することです。 多くのデベロッパーは console.log() を使用して値の変化を追っていますが、console.log() による方法は手間がかかり、効率が悪くなる場合があります。理由は 2 つあります。 まず、console.log() を何回も呼び出すようにコードを手動で編集しなければならない場合があります。 さらに、どの変数がバグに関連しているかを特定できていない場合は、多くの変数をログに出力しなければなりません。

DevTools では、console.log() の代替ツールの 1 つとして Watch Expression を使用できます。Watch Expression を使用して、変数値の経時的な変化を監視します。名前が示しているように、Watch Expression は変数以外にも使用できます。 任意の有効な JavaScript 式を Watch Expression に保存することもできます。 さっそく試してみましょう。

  1. DevTools の [Sources] パネルで、[Watch] をクリックします。セクションが展開します。
  2. [Add Expression] Add Expression をクリックします。
  3. typeof sum を入力します。
  4. Enter キーを押します。DevTools に typeof sum: "string" が表示されます。コロンの右側の値が Watch Expression の結果です。

    [Watch Expression] ペイン 図 1: typeof sum Watch Expression を作成した後の [Watch Expression] ペイン(右下)。 DevTools ウィンドウが大きい場合、[Watch Expression] ペインは、右側の [Event Listener Breakpoints] ペインの上に表示されます。

予想どおり、sum は、数字ではなく、文字列として評価されています。 これがデモのバグの原因です。

DevTools には console.log() に代わるもう 1 つの代替ツール、Console があります。Console を使用して、任意の JavaScript 文を評価します。通常、デベロッパーは Console を使用して、デバッグ時に変数値を上書きします。

ここでは、Console を使用して、見つけたバグの修正案をテストします。 さっそく試してみましょう。

  1. [Console] ドロワーを開いていない場合は、Escape キーを押してドロワーを開きます。 [Console] ドロワーは、DevTools ウィンドウの下部に表示されます。
  2. [Console] ドロワーに parseInt(addend1) + parseInt(addend2) と入力します。
  3. Enter キーを押します。DevTools は文を評価し、6 を出力します。これは、デモで生成されるべき結果です。

    文を評価した後の [Console] ドロワー。 図 1: parseInt(addend1) + parseInt(addend2) を評価した後の [Console] ドロワー。

ステップ 6: 修正を適用する

既にバグの修正方法は特定しています。あとはコードを編集してデモを再度実行し、正しく修正されたか確認するだけです。 修正を適用するために DevTools を閉じる必要はありません。 DevTools UI 内で JavaScript コードを直接編集できます。 さっそく試してみましょう。

  1. DevTools の [Sources] パネルのコードエディタで、var sum = addend1 + addend2var sum = parseInt(addend1) + parseInt(addend2); に置き替えます。この行は、現在一時停止している行の 1 つ上の行です。
  2. Command+S キー(Mac)または Control+S キー(Windows、Linux)を押して変更を保存します。コードの背景が赤に変更され、DevTools 内でスクリプトが変更されたことが示されます。
  3. [Deactivate breakpoints] Deactivate breakpoints をクリックします。コードの背景が青に変わり、スクリプトがアクティブになっていることが示されます。このように設定されていると、DevTools では、設定済みのブレークポイントを無視します。
  4. [Resume script execution] Resume script execution をクリックします。
  5. さまざまな値をデモに入力してみてください。デモで合計が正しく計算されるようになっているはずです。

このワークフローでは、ブラウザで実行されているコードのみに修正が適用されることに注意してください。 ページを実行しているすべてのユーザー向けのコードが修正されるわけではありません。 すべてのユーザーのコードを修正するには、ページを配信しているサーバーで実行されているコードを修正する必要があります。

次のステップ

これで完了です。DevTools で JavaScript をデバッグする方法の基礎を学習しました。

このチュートリアルでは、ブレークポイントの設定方法を 2 つだけ説明しましたが、DevTools では、次のようなその他の方法を多数利用できます。

  • 指定した条件が満たされた場合にのみトリガーされる条件付きブレークポイント。
  • 捕捉された例外または捕捉されていない例外に対するブレークポイント。
  • リクエストした URL が指定した文字列に部分一致した場合にトリガーされる XHR ブレークポイント。

このチュートリアルでは説明していませんが、コードをステップ実行するためのコントロールが他にもいくつかあります。 詳細については、次のリンク先をご覧ください。

フィードバック

このチュートリアルを改善するために、以下の質問にご回答ください。