Techtouch Developers Blog

テックタッチ株式会社の開発チームによるテックブログです

拡張機能で Chrome DevTools に独自パネルを追加してトラブルシュートに役立てよう

こんにちは、カスタマーサクセスエンジニア(CSE)の komo です。

この記事では CSE の主業務の1つにテクニカルサポートがありまして、それを効率化するために作ったツールの話をします。

具体的には Google Chrome 拡張機能で DevTools に独自パネルを追加して、トラブルシュートに有用な情報を表示させるツールです。実物をそのまま紹介はできないため、ひな形を別途作りました。作り方を書くので、同じようなカスタマー系エンジニアの方々に真似してもらって、役立ててもらえると嬉しいです。

ツールの説明

別途作ったひな形はこんなものです。

通信を監視して、特定の通信があると、その内容をパネルに表示します。

以下のようなシーンで利用して欲しいです。

  • HAR から通信内容の成否を確認するとき
  • 画面上にでは表示されない顧客属性を、通信内容から確認するとき

もう少し具体的に、例えば上のキャプチャを例にすると、

  • 登録して日が浅い人向けに出しているコンテンツが表示されなくなってしまった。API のレスポンスは正しいのだろうか?
    • 「Beginner フラグが True なので、データの問題ではない」という切り分けができる。
  • sample.json との通信が発生しているかを見たい
    • 緑背景で通信があったと表示されているので、内容はともかく、通信自体は発生していると切り分けらる

といった感じで使って欲しいです。

ひな形からの発展形

参考までに、私はこのひな形を基礎にして、以下のような仕組み・機能を追加して使っています。

  • Contents Scripts / Service Worker と連動して画面で取得した情報を表示
  • パネルの内容をリセットする
  • パネルに表示するものが多くなったら DOM を操作するためのライブラリを導入
  • パネルのローカルストレージに情報を保存する
  • アイコン設定するなどして見た目を整える
  • よく使うデバッグ用コマンドなどをメモとして書いておく

その他、公式ドキュメントの DevTools の拡張にも活用例が書かれていたり、公式のサンプルもあるので参考にしてみてください。

それでは作り方を書いていきます。

作り方

ステップ1:最小の拡張機能を作る

適当にフォルダ(例:blog)を作って、その中に manifest.json ファイルを作ります。

manifest.json
拡張自体の設定ファイルです。

{
  "manifest_version": 3,
  "name": "Hello Extensions",
  "version": "0.0.1",
}

こんな構成です。

次にブラウザの拡張機能管理画面でデベロッパーモードを有効にして、作ったフォルダをドラッグ&ドロップするか「パッケージ化されていない拡張機能を読み込む」を選択してみてください。

ブラウザが読み込めば OK です。

ステップ2:パネルを追加する

2-1. manifest.json にパネル追加用のコードを追記する

{
    "manifest_version": 3,
    "name": "Hello Extensions",
    "version": "0.0.1",
    "devtools_page": "devtools.html"
}

2-2. devtools.html を作る
devtools.html は特別なもので、パネルとして表示されませんが、必要な JavaScript ファイルを読み込むのに使用されます。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="./devtools.js"></script>
</head>
</html>

2-3. devtools.js を作る
panel.html を呼び出す処理だけ書きます。

chrome.devtools.panels.create(
    "NewPanel",
    "",
    "panel.html"
  );

2-4. panel.html を作る
見た目を整えるために CSS フレームワークの Bulma を利用しています。こちらのページからダウンロードして同じフォルダに置いてください。※ CDN 経由でも動作します。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="./bulma.min.css">
</head>

<body>
    <section class="section">
        <h1 class="title">調査用パネル</h1>
    </section>
</body>

</html>

2-5. パネルが追加されたか確認する
これで Devtools を開き直すと、タブに「調査用パネル」が追加されます。※一番最後に追加されるので、最初は隠れていると思います。

ステップ3:パネルに機能を追加する

3-1. panel.html に追記する
後述の panel.js を読み込む scriptタグと調査に役立てる情報を出すための枠を追記します。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="./bulma.min.css">
    <script src="./panel.js"></script>
</head>

<body>
    <section class="section">
        <h1 class="title">調査用パネル</h1>
        <div class="notification" id="result">Sample.jsonの通信はまだありません。</div>
        <table class="table is-fullwidth">
            <tr>
                <th>Name</th>
                <th>Status</th>
                <th>Beginner</th>
                <th>Language</th>
            </tr>
            <tr>
                <td id="name">-</td>
                <td id="status">-</td>
                <td id="beginner">-</td>
                <td id="language">-</td>
            </tr>
        </table>
    </section>
</body>

</html>

3-2. panel.js を作る
DevTools で使える chrome.devtools.network API の onRequestFinished イベントにリスナーを設置することで、通信を取得し、request.url に sample.json が含まれているときに、sample.json の内容をもとにパネル上の各要素を書き換えています。

chrome.devtools.network.onRequestFinished.addListener(
    (request) => {
        const URL = request.request.url
        if (URL.includes("sample.json")) {
            document.getElementById("result").textContent = "sample.jsonの通信がありました。";
            document.getElementById("result").classList.add("is-success");
            request.getContent((content) => {
                const user = JSON.parse(content).user
                document.getElementById("name").textContent = user.name;
                document.getElementById("status").textContent = user.status;
                document.getElementById("beginner").textContent = user.beginner;
                document.getElementById("language").textContent = user.language;
            });
        };
    }
);

3-3. パネルに機能が追加されたか確認する
ファイル構成はこうなります。

DevTools を開きなおして、以下の画面になっていれば完成です。

特定の通信を受け取ると、以下のように表示が切り替わります。

これで独自パネル完成です!

おまけ:動作確認・キャプチャ取得用に作ったHTMLとJSON

GitHub Copilot にサクッと作ってもらいました。ローカルにサーバーを立ち上げ、HTMLを開き、拡張が動くところを確認してみてください。

HTML

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sample Site</title>
    <script>
        function fetchSampleJson() {
            fetch('./sample.json')
                .then(response => response.json())
                .then(data => {
                    console.log(data);
                })
                .catch(error => {
                    console.error(error);
                });
        }
    </script>
</head>

<body>
    <h1>Sample Site</h1>
    <button onclick="fetchSampleJson()">Fetch Sample JSON</button>
</body>

</html>

JSON

{
    "user": {
        "name": "John Doe",
        "status": "Premium",
        "beginner": true,
        "language": "ja"
    }
}

おわりに

サービスによって、トラブルシュートで確認する情報は様々だと思うので、色々と拡張して自分たちに合うツールを作ってもらえると嬉しいです。

ちなみに、最近出たサイドパネルでも同じことができるか試してみたのですが、DevTools 向けの API が使えませんでした。 ドキュメントには、「拡張機能ページであるため、サイドパネルからすべての Chrome API にアクセスできます。」と書かれているのですが、動きませんでした。残念。

またブログを書く順番がやってきたら、発展形の具体例を書こうと思います。

ではまた。

参考資料