Chrome のよく使うデバッグ方法とその他

✍🏼 作成日 2022年08月07日    💡 更新日 2022年08月12日
❗️ 注意:この記事が作成されてから既に 日が経過しています。情報の鮮度にご注意ください
🖥  説明:Chromeのデバッグ機能は非常に強力で、ここでは私の仕事で最もよく使う機能をいくつか紹介します。
📚  Craft にも公開: https://www.craft.do/s/20CjMjTupEMXFc

Chromeはブラウザであり、フロントエンドエンジニアにとっては強力なデバッグツールでもあります。以下に、私が仕事で最も頻繁に使用する機能をいくつか紹介します。

ブレークポイント

これは最も基本的でよく使われる機能ですが、私が面接した多くの外部委託の方はChromeのブレークポイントデバッグの使用方法を知らないか、聞いたことはあるが使い方がわからないというケースが多いです。以下に基本的な操作方法を簡単に説明します。

ブレークポイントを追加するには、コード内に直接debugger式を1行追加するだけで、コードがこの位置に到達すると実行が停止します:

Image

VSCodeでは、黄色の下線は警告を表します。一般的にこの方法は使用されません。なぜなら、この方法は console.log と比べて明らかな利点がなく、むしろ前者よりも簡潔さに欠けるからです。使用後は削除する必要があり、そうしないとコードが利用不可になるためです。

もう一つの方法は、devtoolsのSourceタブで直接ソースコードを見つけることです。一般的には console.log で出力した後、コンソール右側のファイル名をクリックすると、Sourcesタブでソースコードを確認できます。左下のフォーマットボタンをクリックして整形した後、コード左側の行番号をクリックしてブレークポイントを設定すれば、デバッグが可能です。下図の通りです:

Image

ブレークポイントの後、図中の赤い部分のボタンは左から右へ順に以下の意味を持ちます:

  • 続行実行:クリックすると、ブレークポイントは次のブレークポイントまで直接実行されます。

  • ステップオーバー:現在のブレークポイントが関数内でない場合、ステップと同じく次の行まで実行されます。関数内の場合はその関数をスキップして次の行まで実行されます。

  • ステップイン:非同期コードがない場合、ステップと同じく次の行まで実行されます。非同期コードがある場合、その非同期コードの内部最初の行に入ります。

  • ステップアウト:クリックすると、現在の関数から抜け出します。

  • ステップ:次の同期コード行を実行します。ステップインとは異なり、非同期コードの実行をスキップします。現在のブレークポイントが関数にある場合、その関数呼び出しの内部最初の行に入ります。

  • 一時無効/有効化:初回クリックでブレークポイント機能が一時的に無効化され、ブレークポイントが設定されていないかのようにコードが停止せず実行されます。下部のBreakpointsにあるブレークポイントは全体がグレー表示になります:

Image

Image

  • エラー発生時にブレークポイントで停止 ハイライト後にクリックして有効にすると、コードはあらゆる throw error の場所で自動停止します。catch されているかどうか、HTTPエラーかどうかに関係なく停止します。ただし、必ず下のPause on caught exceptionsにチェックを入れてください。チェックしないと無効になります:

Image

この機能は、コードの実行が1回完了し、ページの読み込みが終了して、インタラクションが開始されるタイミングで有効にするのが最適です。そうしないと、ページにアクセスした瞬間にエラーが発生する可能性があり、Reactにおける正当なエラーも含めて、ページが正常に読み込めなくなることがあります。

公式のブレークポイントの図を直接掲載します:

Image

公式図 👆🏻

上記の図にあるボタンの下には、一連のトグル 三角記号があり、クリック可能です。順番に以下の通り:

  • Watch はブレークポイントでアクセス可能な任意のコンテキスト変数を監視して表示できます。変数が存在しないかアクセスできない場合(例えば a.b.c にアクセスする際にaが存在しない場合)、「利用不可」と表示されます。ブレークポイントで停止した際、この位置に入力された変数は自動的に表示され、マウスをホバーして(上記の公式図のように)変数を確認する必要がなく、非常に便利です。

  • Breakpoints は既存のブレークポイントを表示します。チェックボックスにチェックが入っているものは有効なブレークポイントで、チェックが入っていないものは一時的に無視されるブレークポイントです(一時的にチェックを入れたり外したりできます)。

Image

現在実行中のブレークポイントは黄色の背景で表示されます。

  • Threads は現在呼び出されているファイルのスレッドを表し、現在のページのJavaScriptスレッドはMainと表示されます。この部分は通常使用されませんが、Web Workerのデバッグに有用であり、現在のページでChromeブラウザの拡張機能をデバッグする際にも使用できます。

  • Scope には現在のブレークポイントでアクセス可能な変数の値が表示されます。JavaScriptのクロージャとコールスタックの特性により、多くのクロージャ内の変数が表示されます:

Image

  • Call Stack とは関数の呼び出しスタックを指し、最上位が最も最近の呼び出しです。異なる関数をクリックすることで、それらの間を行き来できます。注意点として、ジャンプ時に実際にその位置まで再度実行されるわけではなく、その位置のクロージャ変数を確認するための機能です。

UI ブレークポイント

UIの問題がなぜそのように変化するのか分からない、または特定できない状況があります。例えば、同僚がボタンにホバーした際に色が変わるコードを書いたとします。あなたはこのロジックに新たな処理を追加する必要がありますが、彼のコードがどのファイルに書かれているか分かりません(彼は引き継ぎもせずに休暇に入ってしまいました、困った!)。

ボタンにホバーするとクラス名が追加されることに気づいたら、DOMブレークポイントを使用してデバッグできます。Elementsタブで、調査したい要素を右クリックします:

Image

UIブレークポイントを使用すると、指定したUIイベントが実行される直前のコードの時点で実行を停止できます。UIイベントには以下が含まれます:

  • サブツリーの変更:サブツリーに追加や属性変更などの変更があった場合、そのロジックが実行される直前でコードを停止します。

  • 属性の変更:現在右クリックした要素に変更があった場合、そのロジックが実行される直前でコードを停止します。

  • ノードの削除:現在右クリックした要素が削除された場合、そのロジックが実行される直前でコードを停止します。

例として、飛書ドキュメントでは、blockがフォーカスされるとノードにfocusクラス名が追加されます:

Image

Image

この時点で attribute modifications を使用してブレークポイントを設定できます:

Image

もちろん、デフォルトではオンラインコードは圧縮されています。左下の {} をクリックするとフォーマットされます:

Image

フォーマット後、Chromeは新しいタブを作成し、ファイル名の末尾に:formattedを追加します。

Image

注意すべき点として、右クリックした要素の変更が親ノードの変更(例えば親ノード全体が削除される場合)である場合、UIブレークポイントは実行されません。

Overwrite

Charlesには「Map js」という類似機能(記憶が正しければ)、ProxyManでは「Map Local」と呼ばれる機能があり、いずれも同じ意味です。

場合によっては、リリース/テストのプロセスが長い(特にエディタのような基本ツールコンポーネントでパッケージ公開が必要な場合)ため、特定のケースを迅速に検証したい時に不便を感じることがあります。そのような場合、ChromeのOverwrite機能が利用できます。

この機能はCharlesの「Map js」機能と類似しており、ローカルファイルをページのリクエストに対するレスポンスとして使用できます。まずSourcesでこの機能を有効にする必要があります。もちろん、ローカルファイルの保存場所が指定されていない場合は、先に場所を指定する必要があります:

Image

この時、Chromeはそのパスへの完全なアクセス権限が必要であることを通知します。許可すれば問題ありません:

Image

ローカルフォルダを選択した後(ここでは ~/Developer/Overwrite フォルダを選択しています)、Overwrite 機能を有効にできます:

Image

次に、Network タブに移動し、css/jsなどのリソースを選択します。ここではjsを選択しました:

Image

注意してください。SourcesOverwrite を有効にしていない場合、ここに Save for overrides は表示されません。

その後、このファイルを自由に編集し、ページをリフレッシュして変更後の効果を確認できます。

留意点として、jsファイルのリクエストにタイムスタンプが付いている場合、Overwriteは効果を発揮しません。Chromeはファイルをマッピングする際に厳密なパスマッチングを使用するためです。

スニペット

正確にはこれは「デバッグ方法」とは言えませんが、普段のコード検証用のスニペットもここに保存しています。Sublime(入力済みの変数を自動補完できる)のような感じで、とても便利です:

Image

ファイルシステム

この機能は上記の機能と同じ場所にあり、ブラウザ内での変更をリアルタイムでローカルファイルシステムに同期するために使用されます。この機能は、Expressのようなサーバーがjs/css/htmlなどを返すシンプルなHTML Webサービスのローカルデバッグ時に適しています。

しかし、この機能は公式にReactアプリには適さないと明言されています。現在のプロジェクトのほとんどはReactやVueなどのモダンフレームワークで構築されているため、この機能はあまり使用されません。ここでは公式スクリーンショットを掲載します:

Image

その他

MacVim

上記のOverwriteで取得したjsファイルは一般的に圧縮された本番環境のコードであり、サイズが大きい場合があります。そのため、私は通常Vimで開いてフォーマットします。Vimの設定は手間がかかりますが、MacVimはすぐに使える体験を提供しており、少しカスタマイズするだけでより良い作業環境が得られます。MacVimを使う理由は、そのパフォーマンスの高さにあります。数十MBの大きなファイルでも数秒でフォーマットできます。私は通常、js-beautifyを設定してフォーマットを行います。名前はjs-beautifyですが、js、css、htmlをフォーマットできます。

js-beautifyを使用するには、まずvim-plugをインストールする必要があります。これはvimプラグインマネージャーです:https://github.com/junegunn/vim-plug。使用方法はこちらを参照してください:https://github.com/junegunn/vim-plug/wiki/tutorial

注:インストールには「魔法」が必要です。

js-beautifyはこちらを使用します:https://github.com/beautify-web/js-beautify

これは私のvim設定です。[]ショートカットキーをjs-beautifyの呼び出しに割り当てており、毎回コマンドを入力する必要がありません:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
set number
set relativenumber
set smartindent
set autoindent
set hlsearch
set display=lastline
set scrolloff=3
set laststatus=2
set showmatch
set ruler
set guifont=Monaco:h12
syntax on
autocmd FileType *.js setlocal equalprg=js-beautify\ --stdin
nmap [] :%!js-beautify<CR>
colorscheme evening
call plug#begin(has('nvim') ? stdpath('data') . '/plugged' : '~/.vim/plugged')
Plug 'jelera/vim-javascript-syntax'
call plug#end()
if !has('gui')
set term=$TERM
endif

VSCode

VSCodeにもブレークポイントデバッグ機能があります(Chromeカーネルのおかげです)。ただし、Nodeアプリケーションのみをデバッグできます(ブラウザ拡張機能と組み合わせてWebアプリケーションをデバッグすることも可能ですが、すでにChromeがあるため必要ありません)。基本的な使用方法はChromeと似ているので、ここでは説明しません。画像を載せておきます:

Image

- EOF -
この記事の初出: Chrome のよく使うデバッグ方法とその他 - Xheldon Blog