このチュートリアルでは、DevTools で JavaScript の問題をデバッグするための基本的なワークフローを説明します。この記事を読み進めるか、このチュートリアルのビデオ版をご覧ください。
バグを再現する
デバッグの最初のステップは、バグを一貫して再度発生させる一連のアクションを特定することです。
- 新しいタブでこのデモを開きます。
- [Number 1] ボックスに「
5
」と入力します。 - [Number 2] ボックスに「
1
」と入力します。 - [Add Number 1 and Number 2] をクリックします。ボタンの下のラベルに
5 + 1 = 51
と表示されます。結果は6
になります。このバグを、これから修正します。
この例では、5 + 1 の結果が 51 になっています。6 にする必要があります。
[Sources] パネル UI についての理解を深める
DevTools には、CSS の変更、ページ読み込みパフォーマンスのプロファイリング、ネットワーク リクエストのモニタリングなどのさまざまなタスクのためのさまざまなツールが用意されています。[ソース] パネルで JavaScript をデバッグします。
DevTools を開き、[ソース] パネルに移動します。
[ソース] パネルには次の 3 つのセクションがあります。
- ファイルツリーが表示された [Page] タブ。ページによってリクエストされているすべてのファイルがここにリストされます。
- [コードエディタ] セクション。[ページ] タブでファイルを選択すると、そのファイルの内容がここに表示されます。
[デバッガ] セクション。ページの JavaScript を検査するための各種ツール。
DevTools ウィンドウの幅が広い場合、デフォルトでは [Code Editor] の右側に [Debugger] が表示されます。この場合、[Scope] タブと [Watch] タブは、[Breakpoints]、[Call stack] などのセクションと統合され、折りたたみ可能になります。
ブレークポイントでコードを一時停止する
このような問題をデバッグする一般的な方法は、多数の 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 でメッセージを確認する必要があります。ブレークポイントを使用した場合は、コードの構造を知らなくても、関係するコードで一時停止することができます。console.log()
ステートメントには、検査する値を 1 つずつ明示的に指定する必要があります。ブレークポイントを使用すると、その時点のすべての変数の値が DevTools に表示されます。コードに影響する変数が他にもあったことに気付かされる場合もあります。
このように、ブレークポイントを使用するなら、console.log()
を使用する方法よりも速くバグを見つけて修正することができます。
先ほどのデモに戻って、このアプリがどのように動作するかを考えると、経験に基づいて、間違いの合計(5 + 1 = 51
)は [Add Number 1 and Number 2] ボタンに関連付けられた click
イベント リスナーで計算されると推測することができます。そのため、click
リスナーが実行されるタイミング前後のコードを一時停止することになります。イベント リスナー ブレークポイントを使用すると、次のとおりに操作できます。
- [デバッガ] セクションで [イベント リスナー ブレークポイント] をクリックしてセクションを開きます。DevTools に、[Animation] や [Clipboard] など、展開可能なイベント カテゴリのリストが表示されます。
- [マウス] イベント カテゴリの横にある [開く] をクリックします。 DevTools に、click や mousedown などのマウスイベントのリストが表示されます。各イベントの横にはチェックボックスがあります。
[クリック] チェックボックスをオンにします。DevTools は、任意の
click
イベント リスナーが実行されると自動的に一時停止するように設定されました。デモに戻り、[Add Number 1 and Number 2] をもう一度クリックします。DevTools はデモを一時停止し、[ソース] パネルでコード行をハイライト表示します。DevTools はコードの次の行で一時停止しているはずです。
function onClick() {
コードの別の行で一時停止している場合は、正しい行で一時停止するまで [
Resume Script Execution] を押します。
イベント リスナー ブレークポイントは、DevTools で使用できる多くのタイプのブレークポイントの一つにすぎません。いろいろあるタイプをすべて調べておくだけの価値はあります。それぞれのタイプがいろいろな状況で迅速にデバッグするのに非常に役立つからです。各タイプをいつどのように使用したらよいかについては、ブレークポイントでコードを一時停止するを参照してください。
コードのステップ実行
バグの一般的な原因の 1 つは、スクリプトの実行順序が間違っていることです。コードをステップ実行すると、コードを 1 行ずつ実行して、予想とは異なる順序で実行されているコード行を見つけることができます。今すぐ試す:
DevTools の [Sources] パネルで、[
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()
関数のどこかにバグがあることがわかります。コードの各行をステップ実行する代わりに、別のタイプのブレークポイントを使用すると、バグがあると思われる箇所の付近でコードを一時停止することができます。
コード行のブレークポイントを設定する
コード行のブレークポイントは、最も一般的なタイプのブレークポイントです。特定のコード行で一時停止する場合は、コード行のブレークポイントを使用します。
updateLabel()
の最後のコード行を確認します。label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
コードの左側には、この特定のコードの行番号 32 が表示されています。[32] をクリックします。DevTools により、32 の上に青いアイコンが配置されます。このアイコンは、この行にコード行のブレークポイントがあることを示します。これで、DevTools は、このコード行が実行される前に常に一時停止します。
[
] [Resume script execution] をクリックします。スクリプトは、行 32 に到達するまで実行されます。行 29、30、31 で、DevTools はaddend1
、addend2
、sum
の値を表示します。値は宣言の横にインラインで表示されます。
この例では、DevTools は行 32 のコード行のブレークポイントで一時停止します。
変数の値を確認する
addend1
、addend2
、sum
の値に問題がありそうです。これらは引用符で囲まれており、文字として扱われているようです。これがバグの原因であると考えられます。ここでさらに情報を収集しましょう。DevTools には変数値を調べるためのたくさんのツールがあります。
方法 1: スコープを検査する
コードのある行で一時停止すると、[スコープ] タブに、実行のこの時点で定義されているローカル変数とグローバル変数が、それぞれの値とともに表示されます。クロージャ変数が存在すれば、それも表示されます。コード行を一時停止していない場合、[スコープ] タブには何も表示されません。
変数値をダブルクリックして編集します。
方法 2: Watch 式
[Watch] タブでは、時間の経過に伴う変数の値をモニタリングできます。Watch は変数に限定されません。有効な JavaScript 式は [Watch] タブに保存できます。
今すぐ試す:
- [見る] タブをクリックします。
- [ ] [Watch 式を追加] をクリックします。
- タイプ
typeof sum
。 - Enter キーを押します。DevTools に
typeof sum: "string"
が表示されます。コロンの右側の値が式の結果です。
このスクリーンショットは、typeof sum
ウォッチ式を作成した後の [Watch] タブ(右下)を示しています。
予想どおり、sum
は、数字である必要がありますが、文字列として評価されています。これがバグの原因であることが、ここではっきりしました。
方法 3: コンソール
console.log()
メッセージを表示するだけでなく、任意の JavaScript ステートメントを評価するためにも Console を使用できます。デバッグのために、Console を使用して、バグの潜在的な修正をテストすることができます。今すぐ試す:
- [Console] ドロワーを開いていない場合は、Escape キーを押して開きます。DevTools ウィンドウの下部に開きます。
- コンソールで「
parseInt(addend1) + parseInt(addend2)
」と入力します。addend1
とaddend2
がスコープ内であるコード行で一時停止しているので、このステートメントは実行されます。 - Enter キーを押します。DevTools でステートメントが評価され、
6
が出力されます。これは、デモで生成される結果です。
このスクリーンショットは、parseInt(addend1) + parseInt(addend2)
を評価した後の [Console] ドロワーを示しています。
修正を適用する
バグの修正が見つかりました。あとはコードを編集してデモを再度実行し、正しく修正されたか確認するだけです。修正を適用するために DevTools を終了する必要はありません。DevTools UI 内で JavaScript コードを直接編集できます。今すぐ試す:
- [ ] [Resume script execution] をクリックします。
- コードエディタで、31 行目の
var sum = addend1 + addend2
をvar sum = parseInt(addend1) + parseInt(addend2)
に置き換えます。 - Command+S キー(Mac)または Ctrl+S キー(Windows、Linux)を押して、変更を保存します。
- [ Deactivate breakpoints] をクリックします。アクティブであることを示す青色に変わります。この設定の間、DevTools は設定したすべてのブレークポイントを無視します。
- さまざまな値でデモを試してみましょう。デモは正しく計算するようになりました。
次のステップ
このチュートリアルでは、ブレークポイントの設定方法を 2 つだけ説明しましたが、DevTools では、他にも次のような多くの方法を利用できます。
- 指定した条件が満たされた場合にのみトリガーされる条件付きブレークポイント。
- 捕捉された例外または捕捉されていない例外に対するブレークポイント。
- リクエストした URL が指定した文字列に部分一致した場合にトリガーされる XHR ブレークポイント。
各タイプをいつどのように使用したらよいかについては、ブレークポイントでコードを一時停止するを参照してください。
コード ステッピング コントロールには、このチュートリアルでは説明されていませんが、いくつかあります。詳しくは、コード行をステップ オーバーするをご覧ください。