このチュートリアルでは、DevTools で JavaScript の問題をデバッグするための基本的なワークフローについて説明します。以下から、このチュートリアルの続きを読むか、動画をご覧ください。
ステップ 1: バグを再現する
バグを一貫して再現する一連のアクションを見つけることが、デバッグの最初のステップです。
- 新しいタブでこのデモを開きます。
- [数値 1] テキスト ボックスに「
5
」と入力します。 - [数字 2] テキスト ボックスに「
1
」と入力します。 - [Add Number 1 and Number 2] をクリックします。ボタンの下のラベルには「
5 + 1 = 51
」と表示されています。結果は6
になるはずです。このバグを修正します。
この例では、5 + 1 の結果は 51 です。6 になっているはずです。
ステップ 2: ソースパネルの UI について理解を深める
DevTools には、CSS の変更、ページ読み込みパフォーマンスのプロファイリング、ネットワーク リクエストのモニタリングなど、さまざまなタスクに対応するさまざまなツールが用意されています。[Sources] パネルでは、JavaScript をデバッグします。
Command+Option+J キー(Mac)または Ctrl+Shift+J キー(Windows、Linux)を押して、DevTools を開きます。このショートカットを使用すると、[コンソール] パネルが開きます。
[Sources] タブをクリックします。
ソースパネル UI は、次の 3 つの部分で構成されています。
- [ファイル ナビゲータ] ペイン。このページがリクエストするすべてのファイルがここに表示されます。
- [Code Editor] ペイン[File Navigator] ペインでファイルを選択すると、そのファイルの内容がここに表示されます。
- [JavaScript Debug] ペイン。ページの JavaScript を検証するためのさまざまなツール。[DevTools] ウィンドウが広い場合、このペインは [Code Editor] ペインの右側に表示されます。
ステップ 3: ブレークポイントでコードを一時停止する
このような問題をデバッグするための一般的な方法は、大量の console.log()
ステートメントをコードに挿入して、スクリプトの実行時に値を検査することです。次に例を示します。
function updateLabel() {
var addend1 = getNumber1();
console.log('addend1:', addend1);
var addend2 = getNumber2();
console.log('addend2:', addend2);
var sum = addend1 + addend2;
console.log('sum:', sum);
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}
console.log()
メソッドでも処理を完了できますが、ブレークポイントを使用すると処理が速くなります。ブレークポイントを使用すると、コードの実行中にコードを一時停止し、その時点のすべての値を調べることができます。ブレークポイントには、console.log()
メソッドに比べて次のような利点があります。
console.log()
を使用する場合、コンソールにメッセージを表示するには、手動でソースコードを開き、関連するコードを見つけてconsole.log()
ステートメントを挿入し、ページを再読み込みする必要があります。ブレークポイントを使用すると、コードの構造を理解していなくても、関連するコードで一時停止できます。console.log()
ステートメントでは、検査する各値を明示的に指定する必要があります。ブレークポイントが存在すると、DevTools にその時点のすべての変数の値が表示されます。コードに影響を与える可変変数が存在します。
つまり、console.log()
メソッドよりもブレークポイントを使用すると、バグを見つけて修正する時間を短縮できます。
少し離れてアプリの動作について考えると、[Add Number 1 and Number 2] ボタンに関連付けられた click
イベント リスナーで誤った合計(5 + 1 = 51
)が計算されるという知識に基づいて推測できます。そのため、click
リスナーが実行されるタイミングでコードを一時停止することをおすすめします。イベント リスナー ブレークポイントを使用すると、まさにそれが可能になります。
- [JavaScript Debug] ペインで、[Event Listener Breakpoints] をクリックしてセクションを展開します。DevTools に、[Animation] や [Clipboard] などの展開可能なイベント カテゴリのリストが表示されます。
- [マウス] イベント カテゴリの横にある [開く ] をクリックします。DevTools に、クリックやマウスダウンなどのマウスイベントのリストが表示されます。各イベントの横にはチェックボックスがあります。
[クリック] チェックボックスをオンにします。これで、任意の
click
イベント リスナーが実行されると自動的に一時停止するように DevTools がセットアップされました。デモに戻り、もう一度 [Add Number 1 and Number 2] をクリックします。DevTools がデモを一時停止し、[ソース] パネルでコード行をハイライト表示します。DevTools を次のコード行で一時停止する必要があります。
function onClick() {
別のコードで一時停止している場合は、正しい行で一時停止するまでスクリプト実行を再開 を押します。
イベント リスナー ブレークポイントは、DevTools で利用できるさまざまな種類のブレークポイントの一つにすぎません。さまざまなタイプのタイプをすべて記憶しておくと、最終的には、さまざまなシナリオを可能な限り迅速にデバッグできるためです。各タイプをいつ、どのように使用するかについては、ブレークポイントでコードを一時停止するをご覧ください。
ステップ 4: コードをステップ実行する
バグの一般的な原因の一つは、スクリプトの実行順序が間違っていることです。コードをステップ実行することで、コードの実行を 1 行ずつ確認して、想定とは異なる順序で実行されている場所を正確に把握することができます。今すぐ試す:
DevTools の [ソース] パネルで、[Step into next function call]()をクリックして、
onClick()
関数の実行を 1 行ずつステップ実行します。DevTools では、次のコード行がハイライト表示されます。if (inputsAreEmpty()) {
[Step over next function call]()をクリックします。DevTools は、ステップ実行せずに
inputsAreEmpty()
を実行します。DevTools によって数行のコードがスキップされることがわかります。これは、inputsAreEmpty()
が false と評価されたため、if
ステートメントのコードブロックが実行されなかったためです。
これが、コードをステップ実行する際の基本的な考え方です。get-started.js
のコードを見ると、バグが updateLabel()
関数のどこかにあることがわかります。コードの各行をステップ実行するのではなく、別のタイプのブレークポイントを使用すると、バグが存在する可能性のある場所の近くでコードを一時停止できます。
ステップ 5: コード行ブレークポイントを設定する
コード行ブレークポイントは、最も一般的なタイプのブレークポイントです。特定のコード行で一時停止する場合は、コード行ブレークポイントを使用します。
updateLabel()
の最後のコード行を見てみましょう。label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
コードの左側に、コードのこの特定の行の行番号、32 が表示されます。[32] をクリックします。DevTools により、32 の上に青いアイコンが表示されます。これは、この行にコード行ブレークポイントがあることを意味します。DevTools は、このコード行が実行される前に常に一時停止するようになりました。
スクリプト実行を再開アイコン をクリックします。スクリプトは 32 行目まで実行されます。29、30、31 行目では、DevTools によって宣言の横に
addend1
、addend2
、sum
の値が表示されています。
この例では、DevTools は 32 行目のコード行ブレークポイントで一時停止します。
ステップ 6: 変数値を確認する
addend1
、addend2
、sum
の値が疑わしい。これらは引用符で囲まれている、つまり文字列です。これは、バグの原因を説明するうえで適切な仮説です。次に、さらに情報を収集します。DevTools には、変数値を調べるためのツールが多数用意されています。
方法 1: [スコープ] ペイン
コードの行で一時停止すると、[Scope] ペインに、現在定義されているローカル変数とグローバル変数が各変数の値とともに表示されます。該当する場合はクロージャ変数も表示されます。変数値をダブルクリックして編集します。コード行で一時停止していない場合、[Scope] ペインは空になります。
方法 2: Watch Expressions
[Watch Expressions] タブでは、変数の値を経時的にモニタリングできます。名前が示すように、Watch Expression は変数に限定されません。任意の有効な JavaScript 式を Watch 式に格納できます。今すぐ試す:
- [みる] タブをクリックします。
- [式を追加] をクリックします。
- タイプ
typeof sum
。 - Enter キーを押します。DevTools に
typeof sum: "string"
が表示されている。コロンの右側にある値が、Watch Expression の結果です。
上のスクリーンショットは、typeof sum
ウォッチ式を作成した後の [Watch Expression] ペイン(右下)を示しています。DevTools ウィンドウが大きい場合は、[Watch Expression] ペインは、右側の [Event Listener Breakpoints] ペインの上に表示されます。
疑わしいのですが、sum
は、数値であるべきなのに文字列として評価されています。これで、これがバグの原因であることが確認されました。
方法 3: コンソール
Console では、console.log()
メッセージを表示するだけでなく、任意の JavaScript ステートメントを評価することもできます。デバッグに関しては、コンソールを使用してバグの修正の可能性をテストできます。今すぐ試す:
- [コンソール] ドロワーが開いていない場合は、Esc キーを押して開きます。[DevTools] ウィンドウの下部に開きます。
- コンソールで「
parseInt(addend1) + parseInt(addend2)
」と入力します。addend1
とaddend2
がスコープ内にあるコード行で一時停止しているため、このステートメントは機能します。 - Enter キーを押します。DevTools によってステートメントが評価され、
6
が出力されます。これはデモで生成されることが想定される結果です。
上のスクリーンショットは、parseInt(addend1) + parseInt(addend2)
を評価した後の [Console] ドロワーを示しています。
ステップ 7: 修正を適用する
バグの修正が見つかった。あとは、コードを編集してデモを再実行し、修正を試すだけです。修正を適用するために DevTools を終了する必要はありません。JavaScript コードは、DevTools UI 内で直接編集できます。今すぐ試す:
- スクリプト実行を再開アイコン をクリックします。
- コードエディタで、31 行目の
var sum = addend1 + addend2
をvar sum = parseInt(addend1) + parseInt(addend2)
に置き換えます。 - command+S(Mac)または Ctrl+S(Windows、Linux)を押して、変更を保存します。
- 「ブレークポイントを無効化」アイコン をクリックします。アクティブであることを示す色が青色に変わります。設定済みの場合、DevTools は設定したブレークポイントを無視します。
- さまざまな値でデモを試します。デモが正しく計算されるようになりました。
次のステップ
お疲れさまでした。これで、JavaScript をデバッグする際に Chrome DevTools を最大限に活用する方法を学習できました。このチュートリアルで学習したツールとメソッドを使用すると、数え切れないほどの時間を節約できます。
このチュートリアルでは、ブレークポイントを設定する 2 つの方法のみを説明しました。DevTools には、他にも次のような多くの方法があります。
- 指定した条件が true の場合にのみトリガーされる条件付きブレークポイント。
- キャッチされた例外またはキャッチされなかった例外のブレークポイント。
- 指定した部分文字列がリクエストされた URL と一致する場合にトリガーされる XHR ブレークポイント。
各タイプをいつ、どのように使用するかについては、ブレークポイントでコードを一時停止するをご覧ください。
このチュートリアルでは説明されていませんが、コードをステップ実行するためのコントロールがいくつかあります。詳しくは、コード行をステップ オーバーするをご覧ください。