VS Codeを使ってReactアプリをデバッグする方法 - デバッグの生産性を向上させよう

Reactアプリをデバッグするのは、遅くて苦痛なプロセスになることがあります。あちこちでconsole.log()を追加し続け、ようやく正しい場所にたどり着くことも。もしくはもっと高度な方法:Chrome開発者ツールとIDEでコードを編集しながらブレークポイントを行き来してバグを修正していく。

でも、適切なツールと戦略的なアプローチを使えば、デバッグはずっと簡単になることができます。楽しくさえ感じるかもしれませんよ?

なんと、大人気のVS Codeは IDEから直接Reactアプリをデバッグすることを非常にシンプルにしてくれます。結果:簡単なセットアップとより生産的なデバッグワークフロー。

このページでは、VS CodeをReactアプリのデバッガとしてセットアップする方法を見ることができます。Next.jsアプリケーションの小さな問題をデバッグする方法を示し、VS Codeで(条件付き)ブレークポイントを使い、関数にステップインし、変数の検査と編集を行います。これらすべては構造化されたデバッグアプローチと組み合わせて、バグはすぐに修正されます。

以下に、VS Codeのデバッガのセットアップと使用方法を示す短いビデオがあります。このページでは、スクリーンショット付きの詳細なステップバイステップのチュートリアルを見つけることができます。

目次

  1. VS CodeでChromeを起動する
  2. VS Codeのデバッガを使う
  3. アクションで見るVS Codeデバッガ
    1. VS Codeでブレークポイントを使う
    2. 条件付きブレークポイントで救済
    3. 根本原因の発見
    4. デバッガで変数を検査・編集する
    5. 関数にステップインする

VS CodeでChromeを起動する

ReactアプリをVS Codeデバッガでデバッグを始めるのは驚くほどシンプルです。VS Codeにlaunch.json設定を作成させて、少し調整するだけです。そのファイルはリポジトリの.vsocdeフォルダにあります。

アプリによっては以下が必要です:

  • urlフィールドを調整する(ここではポートを3000に変更します)
  • webRootを調整する(例えばコードがsrcフォルダの中にある場合、create-react-appアプリのように${workspaceFolder}${workspaceFolder}/srcに変更します)

これで、再生ボタン ▶️ を押して、デバッグモードでChromeブラウザを開始することができます。VS Codeデバッガは自動的にこのブラウザにアタッチされます。

注:手動でChromeをデバッグモードで実行し、"attach"設定を使用してVS Codeデバッガにアタッチすることもできます。でもわざわざ複雑にする理由は見当たりません。

すでにlaunch.jsonファイルがあるか、またはそれに別の設定を追加したい場合は、Intellisenseを使う(例えば、Macではcmd + spaceを押す)と提案が得られます。

以下が私のlaunch.jsonファイルです:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Run Chrome",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}"
    }
  ]
}

VS Codeのデバッガを使う

デバッガを使用するためには2つのことが必要です:

  1. Reactアプリを実行する(例えばnpm startを実行する)。
  2. 再生ボタン ▶️ を押してVS Code経由でChromeを起動する。

これで、Chrome開発者ツールで行うようにデバッガを使用することができます。それに慣れていない場合は、下の例で見ることができます。

アクションで見るVS Codeデバッガ

以下の状況を想像してみましょう:我々は本番環境でNext.jsアプリに取り組んでいる開発者です。実際のユーザーがいて、何も壊れるべきではありません。

最も重要なページの1つは、これまでこのように見えていました(ここでそのデプロイされたバージョンを見ることができます):

しかし、突然何かが壊れているとの報告があります(ここでデプロイされたバージョンを見る):

ああ、このバグはどうして本番環境に入ったんだろう? 私たちのお客様は怒っています。彼らは我々のアプリに頼っていて、良いお金を払っています。当然、管理者たちは大騒ぎしています。

でも、我々開発者は冷静を保ちます。正しいデバッグアプローチを使えば、このバグをすぐに修正できる可能性があります。

本番環境のエラーメッセージからは多くは分かりません。なので、まず私たちのローカルマシンでアプリを実行します。

このエラーは本番ウェブサイトで見るものよりもずっと良いです。2つの重要な情報を提供してくれます:

  1. エラーメッセージ「Cannot read properties of null」。
  2. エラーが発生したファイル名と行:issue-row.tsxの49行。

ファイルをVS Codeで開くのは本当にシンプルです。エラーメッセージでのファイルパスは実際リンクになっています:

エラーメッセージはissueプロパティがおそらくいつかnullになることを示しています。それを確認するために、ブレークポイントを追加してみましょう。行番号の隣の空白スペースをクリックするだけです。

緑色の「リスタート」ボタン↻を押すと、ページがリフレッシュされます。

プロセスを加速するために、キーの組み合わせ(私の場合はCmd + Shift + F5)を使うこともできます。あなたのキーを見つけるには、ボタンの上にカーソルを合わせてみてください。

コード実行はブレークポイントで停止し、同時にウェブサイトはロード中の状態でフリーズします。

上のスクリーンショットで見ての通り、issueプロパティは最初のレンダリング中に定義されています。

なので、「続行」ボタン⏯️やF5を数回押します。問題はIssueRowコンポーネントがたくさんレンダリングされていることです。だから、正しい問題を見つけるまで「続行」を押し続けるのはすぐにうっとうしくなります。

条件付きブレークポイントで救済

「続行」をずっと押す代わりに、定義された問題を全てスキップし、nullishなものだけに停止したいと思います。

それを行う一番簡単な方法は、ブレークポイントに条件を追加することです。ブレークポイントの上で右クリックして「ブレークポイントを編集」を選びます。

これでJavaScript式を入力できます。私たちの場合、issue === nullに停止したいです。

Enterを押してコード実行を続けると、少なくとも1つの問題がnullであることを確認できます。

正直なところ、これは私たちにとって全く新しいニュースではありません。なぜなら、既にエラーメッセージからわかっていたからです。でも、問題を確認できるだけでも良いことです。

根本原因の発見

では、もう少し深く掘り下げてみましょう。シンプルなJavaScriptプログラムなら、コールスタックをたどるか「ステップアウト」ボタン(⬆️)を押して問題の根本原因を見つけることができます。

しかし、React(や他のフレームワーク)ではそう簡単ではありません:

「コールスタック」パネルでは、「IssueRow」以外に私たちのコードファイルは見えません。他のすべては内部Reactファイルです。

これではあまり役に立ちません。

残念ながら、IssueRowコンポーネントがレンダリングされる場所を手動で見つける必要があります。ここではVS Codeのグローバル検索機能が最も役に立ちます。

ファイルを開き、コンポーネントのreturn文の直前に別のブレークポイントを追加します。

次に、デバッグコントロールまたはF5でリフレッシュボタン↻を押します。

すばらしい、items配列の中に確かにnullのアイテムが1つあることがわかります。

デバッガで変数を検査・編集する

このnull値がバグの原因であるという仮定があります。しかし、コードをいじり始める前に、デバッガ内で変数を編集することでこの仮定を簡単に確認することができます。

コード実行を続けると、ウェブサイト上のエラーが消えるのを見ることができます。問題リストの7番目と8番目のアイテムが重複しているのが予想通りです。

これは、null値がデータ配列の問題であるという私たちの仮定を検証します。

私たちのバグに対する解決策は単純です:データから全てのnull値をフィルターアウトすればバグを修正できます。もちろん、フィルター関数をコンポーネント内に実装することもできますが、データソースに近い場所の方が適しているかもしれません。このように他の(未来の)コンポーネントも同じ修正から恩恵を受けることができます。

関数にステップインする

もう少し掘り下げるために、コンポーネントの始まりを見てみましょう。null値を持つitems配列はissuePage変数から来ています。そして、それはフックからきています。

そこで別のブレークポイントを設定し、またリフレッシュボタンを押します。コード実行はブレークポイントで止まります。

「ステップイン」ボタン⬇️を使ってそのフックを調べることができます。最初に開かれるファイルは、またしても内部のReactファイルです。

しかし、今回は運が良いです。何回か「ステップイン」ボタンを押した後、「useIssues」フックにたどり着きます。

もう少しよく見ると、getIssues関数はデータをフィルタリングする良い候補です。

残念なことに、何らかの理由でgetIssues関数にステップインすることも、関数内のブレークポイントでコード実行が停止することもできません。デバッグの経験があるなら、こんな不便なことが時々あることは分かっているでしょう。

とにかく、それに私たちを引き留めさせることはしません。問題をフィルタするために少しコードを追加します。

returnを押すと、バグが修正されたことを確認できます。

コミット、プッシュ、デプロイ。皆満足です。

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/profydev/how-to-debug-react-apps-with-vs-code-boost-your-debugging-productivity-1k05