※ この記事は、PLAID Advent Calendar 2017 9日目です。
こんにちは、プレイドの @jumtech (twitter: @jumpei_ikegami)です。
BizDevチームでエンジニアをしています。
趣味はTech系ポッドキャストの配信です。
Matzさんも聴いてます。(語弊)
ポッドキャスト聴いてると、いきなり私個人向けに挨拶される驚き。 #しがないラジオ
— Yukihiro Matsumoto (@yukihiro_matz) 2017年9月16日
私は社内では珍しく、ビジネス側のチームでエンジニアをしています。
そこで、技術的なサポート業務をChromeデベロッパーツール拡張で効率化した話を書きます。
まとめ
- Chromeデベロッパーツールは簡単に拡張できる
- Chromeデベロッパーツール拡張を使って、自分好みのWebサイトインスペクタが作れる
なぜ必要だったか
弊社では、Web接客プラットフォーム「KARTE」を開発しています。
ざっくり言うと、エンドユーザーの属性やリアルタイムの行動に応じて、KARTE導入サイト上で、動的にコンテンツを出し分けるツールです。
そのため、「なんかコンテンツ出ないんだけど?」みたいな問い合わせが、社内外を問わず飛んできます。
これまでは、ChromeデベロッパーツールのNetworkタブで弊社サーバーとの通信を探して、Preview画面でgzipされたJavaScriptを解読していました。
これはつらい、つらい。
技術の力で解決です。
作ったものが、こちら
toB向けなので、画像だけで失礼します。
なんと、Chromeデベロッパーツールを拡張すると、カスタムのタブを1つ追加し、専用のviewを追加することができます。
Networkタブに表示されるようなrequest/responseの内容も取得できるので、通信の中で気になる部分だけをpick-upして表示するようなことができます。
Chrome拡張で<title>の中身を表示する
世の中には、2種類のChrome拡張があります。
- ただのChrome拡張
- Chromeデベロッパーツール拡張
もう少し詳しく言うと、Chrome拡張は実行されるコンテキストの違う複数のscriptを組み合わせて作ることができ、それらscript毎にできることが違います。
実は、ただのChrome拡張といえども、閲覧ページのDOMに触ることは可能です。
例えば、ポッドキャストのshow noteを書くとき、
「リンクを貼るページの<title>の中身だけをコピペしたい」
みたいなことがあります。
デベロッパーツール拡張の前に、まずは試しに、それを作ります。
ブラウザのコンソールにtitleタグの中身を出す
まず、適当なフォルダを作り、manifest.json
(Chrome拡張としての設定ファイル)を作成します。
{
"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
を作成します。
const title = document.getElementsByTagName('title')[0].innerText;
console.log(title);
これで、拡張機能ができました。
はい、簡単です。
あとは、Chromeでchrome://extensions/
にアクセスし、
- 右上の「デベロッパーモード」にチェック
- 左上の「パッケージ化されていない拡張機能を読み込む」
から、manifest.jsonが存在するフォルダを読み込みます。
chromeの上部バーにアイコンが追加され、Chrome拡張として登録されたことがわかります。
試しに、KARTEのサイトを開いてみると、
content.js
が実行され、Consoleにtitleタグの中身が出力されました。
Chrome拡張自体の表示領域が欲しい!
いちいちConsoleを開いてタイトルをコピペするのは面倒なので、Chrome拡張自体の表示領域を確保します。
そのために、Chrome拡張のbrowserActionにpopupを登録します。
{
...
"browser_action": {
"default_popup": "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を書くとなぜか動かないので、外部ファイルに切り出します。
document.getElementById('title').innerText = 'ここにタイトルを表示したい';
再度 chrome://extensions/
にアクセスし、「リロード」ボタンを押すと、
アイコンを押したときに、popup.htmlを表示させることができます。
popup.htmlのコンテキストで要素の検証やconsoleを見たい場合は、アイコンを右クリックして、「ポップアップを検証」を押すと、popup用のデベロッパーツールが開きます。
content.jsからpopup.jsにタイトルを受け渡す!
popup.jsが参照するDOMはpopup.htmlなので、直接ページ上のDOMを触ることができません。
そこで、閲覧ページのDOM操作はcontent.jsに任せて、その結果をMessagePassingで受け取ります。
content.js側では、メッセージを受け取った場合のイベントリスナを登録します。
閲覧ページのタイトルを含めて、レスポンスを返します。
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
const title = document.getElementsByTagName('title')[0].innerText;
sendResponse( {title: title} );
});
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拡張をリロードして右上のアイコンをクリックすると、問題なくページタイトルが表示されていることがわかります。
完成!
以上で、実用的な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拡張ライフとスプラトゥーンライフをお送りください!