chrome-extension
PLAIDDay 9

Chromeデベロッパーツール拡張で、Techサポートを効率化する

※ この記事は、PLAID Advent Calendar 2017 9日目です。

こんにちは、プレイドの @jumtech (twitter: @jumpei_ikegami)です。

BizDevチームでエンジニアをしています。

趣味はTech系ポッドキャストの配信です。

Matzさんも聴いてます。(語弊)

私は社内では珍しく、ビジネス側のチームでエンジニアをしています。

そこで、技術的なサポート業務をChromeデベロッパーツール拡張で効率化した話を書きます。

まとめ

  • Chromeデベロッパーツールは簡単に拡張できる
  • Chromeデベロッパーツール拡張を使って、自分好みのWebサイトインスペクタが作れる

なぜ必要だったか

弊社では、Web接客プラットフォーム「KARTE」を開発しています。

ざっくり言うと、エンドユーザーの属性やリアルタイムの行動に応じて、KARTE導入サイト上で、動的にコンテンツを出し分けるツールです。

そのため、「なんかコンテンツ出ないんだけど?」みたいな問い合わせが、社内外を問わず飛んできます。

これまでは、ChromeデベロッパーツールのNetworkタブで弊社サーバーとの通信を探して、Preview画面でgzipされたJavaScriptを解読していました。

これはつらい、つらい。

技術の力で解決です。

作ったものが、こちら

----------2017-08-14-5.30.51.png

toB向けなので、画像だけで失礼します。

なんと、Chromeデベロッパーツールを拡張すると、カスタムのタブを1つ追加し、専用のviewを追加することができます。

Networkタブに表示されるようなrequest/responseの内容も取得できるので、通信の中で気になる部分だけをpick-upして表示するようなことができます。

Chrome拡張で<title>の中身を表示する

世の中には、2種類のChrome拡張があります。

  • ただのChrome拡張
  • Chromeデベロッパーツール拡張

もう少し詳しく言うと、Chrome拡張は実行されるコンテキストの違う複数のscriptを組み合わせて作ることができ、それらscript毎にできることが違います。

概念図
devtools-extension (1).png

実は、ただのChrome拡張といえども、閲覧ページのDOMに触ることは可能です。

例えば、ポッドキャストのshow noteを書くとき、
「リンクを貼るページの<title>の中身だけをコピペしたい」
みたいなことがあります。

デベロッパーツール拡張の前に、まずは試しに、それを作ります。

ブラウザのコンソールにtitleタグの中身を出す

まず、適当なフォルダを作り、manifest.json(Chrome拡張としての設定ファイル)を作成します。

manifest.json
{
  "name": "showTitle",
  "version": "1",
  "manifest_version": 2,
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ]
}

仕様はこちら

manifest_versionは、manifest.jsonのフォーマット自体のversionなので、最新である2を指定します。

content_scriptsプロパティでは、URLパターン毎に、展開するJavaScriptやCSSを登録できます。

マッチパターンの書き方は、こちらをどうぞ。

次に、閲覧ページと同じコンテキストで実行されるcontent.jsを作成します。

content.js
const title = document.getElementsByTagName('title')[0].innerText;
console.log(title);

スクリーンショット 2017-12-06 10.53.08.png

これで、拡張機能ができました。
はい、簡単です。

あとは、Chromeでchrome://extensions/にアクセスし、

  • 右上の「デベロッパーモード」にチェック
  • 左上の「パッケージ化されていない拡張機能を読み込む」

から、manifest.jsonが存在するフォルダを読み込みます。

スクリーンショット 2017-12-06 10.51.12.png

chromeの上部バーにアイコンが追加され、Chrome拡張として登録されたことがわかります。

試しに、KARTEのサイトを開いてみると、

スクリーンショット 2017-12-06 10.53.08.png

content.jsが実行され、Consoleにtitleタグの中身が出力されました。

Chrome拡張自体の表示領域が欲しい!

いちいちConsoleを開いてタイトルをコピペするのは面倒なので、Chrome拡張自体の表示領域を確保します。

そのために、Chrome拡張のbrowserActionにpopupを登録します。

manifest.json
{
...
  "browser_action": {
    "default_popup": "popup.html"
  }
}
popup.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
  .title { width: 500px; }
  </style>
</head>
<body>
  <div id="title" class="title"></div>
  <script src="popup.js"></script>
</body>
</html>

html内に直接scriptを書くとなぜか動かないので、外部ファイルに切り出します。

popup.js
document.getElementById('title').innerText = 'ここにタイトルを表示したい';

再度 chrome://extensions/にアクセスし、「リロード」ボタンを押すと、

スクリーンショット 2017-12-06 11.13.05.png

アイコンを押したときに、popup.htmlを表示させることができます。
popup.htmlのコンテキストで要素の検証やconsoleを見たい場合は、アイコンを右クリックして、「ポップアップを検証」を押すと、popup用のデベロッパーツールが開きます。

content.jsからpopup.jsにタイトルを受け渡す!

popup.jsが参照するDOMはpopup.htmlなので、直接ページ上のDOMを触ることができません。

そこで、閲覧ページのDOM操作はcontent.jsに任せて、その結果をMessagePassingで受け取ります。

content.js側では、メッセージを受け取った場合のイベントリスナを登録します。
閲覧ページのタイトルを含めて、レスポンスを返します。

content.js
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  const title = document.getElementsByTagName('title')[0].innerText;
  sendResponse( {title: title} );
});

popup.js側では、メッセージの送信を行います。

popup.js
chrome.tabs.query({currentWindow: true, active:true}, (tabs) => {
  chrome.tabs.sendMessage(tabs[0].id, {text:'titleちょうだい'}, (res) => {
    document.getElementById('title').innerText = res.title;
  });
});

ご存知のように、Chromeでは気付くと大量のウィンドウとタブが量産されているので、対象のタブを特定するためにqueryプロパティで対象タブの絞り込み条件を指定しています。

ここでは、現在のウィンドウでアクティブなタブを選択します。
タブが特定できたら、そのタブに対してメッセージと、レスポンスが帰ってきたときのコールバックを渡します。

そのコールバックの中で、content.jsから受け取ったtitleを、popup.html側のDOMに追加します。

再度Chrome拡張をリロードして右上のアイコンをクリックすると、問題なくページタイトルが表示されていることがわかります。

スクリーンショット 2017-12-06 11.36.42.png

完成!

以上で、実用的なChrome拡張ができました。

実際のソースコードは、以下をご覧ください。
https://github.com/jumtech/show-title-extension

いざ、デベロッパーツール拡張へ!

ここまでが、「ただのChrome拡張」でできる最低限のことでした。

ここから、いよいよみんな大好きChromeデベロッパーツールの拡張に進みます。

と思ったのですが、なんとちょうどいいブログ記事を見つけたので、そちらをご覧ください。(宣伝)

Chromeデベロッパーツールに独自機能を追加する6つのステップ | PLAID engineer blog

この記事では、閲覧ページからTwitterサーバーへのリクエストを検知し、Twitter埋め込みを使っているかを一瞬で判別するツールを作る例を紹介しています。

また、類似の内容でWe Are JavaScripters!という勉強会に個人的に登壇した資料もあります。

Chromeデベロッパーツールを自分色に染める // Speaker Deck

こちらでは、閲覧ページで使われているWeb解析系のツールを可視化するという同様の機能実装に加えて、デベロッパーツール内へのVue.jsの導入についても触れています。

なお、これらの執筆時点と現在で、重要な変更点が1点あります。

当時の持ちブキは「銀モデ」でしたが、現在は「黒ZAP」です。

上記に注意して、楽しいChrome拡張ライフとスプラトゥーンライフをお送りください!