ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

Visual Studio CodeでChrome Extensionをデバッグする

俺的 Chrome Extension ブーム。

まだChrome Extensionが自分の中で熱いうちにもう一つ作って公開してみた。

といっても、新しいアイデアが思いついた訳ではなく、昔Userscriptとして作った以下二つの機能をがっちゃんこ()して、一つのChrome Extensionに焼きなおしたもの。

uncaughtexception.hatenablog.com

uncaughtexception.hatenablog.com

個人的には、Faviconを変えたり点滅させたりするのがお気に入りだけど、公開後の反応を見る限り、デスクトップ通知の方が人気の様子。

ただ、Userscriptからの移植で一番仕組みを変えたのがデスクトップ通知だったので、頑張った甲斐はあった。

という訳で、インストールしてください。星、待ってます。

chrome.google.com

と、ここまでが

Extension作りがひと段落した時に書いて公開し忘れてた内容。

完全にタイミングを逃したので、ネタを追加。

開発中の悩み

Chrome Extensionを作ってて思ったこと。

Chrome Extensionにはcontent script/popup/service workerの3種類のスクリプトが入ってて、VSCodeがない世界では開発者ツールだけ頑張るので、ブレイクポイントとか変数チェックしようとすると、見た目同じウィンドウがいくつか立ち上がる。

すると、いちいち

これは、、、どのスクリプトのウィンドウだ???

となって、割と大変だった。

せっかくVSCodeでコードを書いてたのだから、デバッグくらいできるに違いない、と調べた結果をまとめた。

前準備

まず.vscode/launch.jsonを作る。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Debug on Chrome",
      "port": 9222,
      "runtimeArgs": [
        "--load-extension=${workspaceFolder}"
      ],
    }
  ]
}

内容はChromeの起動。
ほぼVSCodeが作るテンプレのまんま。

追加したのは、--load-extension オプションで manifest.json があるディレクトリを選ぶくらい。
プロジェクトルートに置いているなら --load-extension=${workspaceFolder} でよし。

いざデバッグ

デバッグの開始は通常通りF5キーで。

ここから、1つのVSCodeウィンドウで、content script/popup/service workerの3種類のスクリプトデバッグする。

content script/popupのデバッグ

といっても、content scriptとpopupのスクリプトは、特に何もすることなく、VSCodeからChromeのプロセスにアタッチできる。
ブレイクポイントを置けば、そこで処理はポーズしてくれるし、変数の確認も簡単。

ちなみにpopupを開くと勝手にpopup用の開発者ツールが立ち上がる。
けどpopupのデバッグだけなら閉じてもオーケー。

問題は次のservice worker。

service workerのデバッグ

service workerの場合、content scriptやpopupの時はできていた、コード内のブレイクポイントが有効化ができず、ポーズや変数確認ができない。

一方、chrome://extensions からservice worker用の開発者ツールを開けば、開発者ツール内で開いたソースに置いたブレイクポイントでポーズしたり変数確認はできるが、その場合、

の3つのウィンドウを見ることになる。

まぁ、3つくらいならましなのかもしれない。

それでも、、、!

「どうしてもデバッグVSCodeだけでやりたい!」という強い想いがあるなら、以下の手順をやると デバッグVSCodeにまとめられる。

このデバッグのやり方を見つけるのが難しかった。
それでも割と煩雑な方法。

  1. まずVSCodeF5キーでデバッグを開始
    この時点で、content script/popupのデバッグはできる

  2. Chromeが立ち上がったら、Ctrl + nとかで、もう1枚ウィンドウを作り chrome://extensions を開く。
    手順 1. のデバッグ開始で立ち上がった方を window1、ここで手動で作ったウィンドウを window2 としておく。

  3. window2 でservice workerが inactive(または無効) になっていることを確認する。

    なっていない場合、大抵は30秒ほど放置すると自動的に inactive になる(という、Chrome Extensionの仕様?バグ?)。

  4. window2拡張機能アイコンをクリックして、popupを表示する。
    この時、開発者ツールが勝手に立ち上がるが、この後使うのでまだ閉じない。

  5. 立ち上がった (popup用の) 開発者ツールの Application タブを開き、service workerについての情報が出ているか確認する。

  6. Status 欄にある start をクリックする。

    ここまで来たら、手順 4. で開いた開発者ツールは閉じていい。
    けど、popupは閉じちゃダメ。絶対に!

以上の手順でVSCodeがservice workerにアタッチして、デバッグができるようになる。

VSCodeCALL STACK には、popupの下にservice workerがぶら下がっているのがわかる。

こっちの方法でVSCodeChrome Extensionにアタッチすると、VSCodeデバッグを集約できるので、デバッグ作業中に操作するウィンドウは

の2つだけになって、割とスッキリしたんじゃないだろうか。

左下にpopup表示用Chrome(window2)もあるけど、こっちはデバッグ中は操作する必要ないのでノーカウント。

留意点として、手順 4. で window2 で開いたpopupをうかつに操作してpopupが閉じてしまう*1と、VSCodeとservice workerの接続が切れるので、デバッグ中は触らない方がいい。

他のウィンドウを操作する分にはpopupは閉じない。
上の手順では、手順 2. でpopup表示用と動作確認用の2つのウィンドウを分けたので、popupのスクリプトデバッグwindow1 でできる。
邪魔だと思うなら、他のウィンドウの裏に置いて隠せばいい。

もしpopupを閉じてしまい接続が切れてしまったら、手順 3. からやり直すと再接続ができる。

残る謎と課題

なぜservice workerを、popupの開発者ツールから起動することが、service workerへのアタッチにつながるのかは、実は全く理解してない。

あとpopupがないChrome Extensionだとこの方法が使えないかもしれない。
開発中はダミーのpopupが必要。

正直なところ、これが正規の方法かはわからないし、どちらも一長一短あるので、デバッグ準備とデバッグ作業中のどっちを楽にしたいか、選べばいいと思う。

あと、この知見が活かせる次のネタがまだないのが大きな課題。

*1:ウィンドウの最少化操作でもpopupが閉じちゃう