概要
DevTools 拡張機能は、Chrome DevTools に機能を追加します。新しい UI パネルやサイドバーの追加、検証対象のページとのやり取り、ネットワーク リクエストに関する情報の取得などを行うことができます。おすすめの DevTools 拡張機能をご覧ください。DevTools 拡張機能は、DevTools 固有の拡張機能 API の追加セットにアクセスできます。
DevTools 拡張機能は、他の拡張機能と同様に構成されています。バックグラウンド ページ、コンテンツ スクリプト、その他のアイテムを含めることができます。また、各 DevTools 拡張機能には DevTools ページがあり、DevTools API にアクセスできます。

DevTools ページ
DevTools ウィンドウが開くたびに、拡張機能の DevTools ページのインスタンスが作成されます。DevTools ページは、DevTools ウィンドウの有効期間中存在します。DevTools ページは、DevTools API と拡張機能 API の限定されたセットにアクセスできます。具体的には、DevTools ページで次の操作を行うことができます。
devtools.panelsAPI を使用してパネルを作成し、操作する。- `
devtools.inspectedWindow` API を使用して、検証対象のウィンドウに関する情報を取得し、検証対象のウィンドウでコードを評価する。 devtools.networkAPI を使用して、ネットワーク リクエストに関する情報を取得する。
DevTools ページでは、ほとんどの拡張機能 API を直接使用できません。コンテンツ スクリプトがアクセスできる extension API と runtime API のサブセット
にアクセスできます。コンテンツ
スクリプトと同様に、DevTools ページはメッセージ パッシングを使用してバックグラウンド ページと通信できます。例については、コンテンツ スクリプトの挿入をご覧ください。
DevTools 拡張機能を作成する
拡張機能の DevTools ページを作成するには、拡張機能のマニフェストに devtools_page フィールドを追加します。
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
拡張機能のマニフェストで指定された devtools_page のインスタンスは、開かれた DevTools ウィンドウごとに作成されます。このページでは、他の拡張機能ページをパネルやサイドバーとして
DevTools ウィンドウに追加できます。devtools.panels API を使用します。
chrome.devtools.* API モジュールは、DevTools ウィンドウ内に読み込まれたページでのみ使用できます。コンテンツ スクリプトや他の拡張機能ページには、これらの API はありません。したがって、これらの API は DevTools ウィンドウの有効期間中のみ使用できます。
また、一部の DevTools API はまだ試験運用版です。試験運用版の API のリストと使用方法のガイドラインについては、chrome.experimental.* API をご覧ください。
DevTools UI 要素: パネルとサイドバー ペイン
ブラウザ アクション、コンテキスト メニュー、ポップアップなど、通常の拡張機能 UI 要素に加えて、DevTools 拡張機能では UI 要素を DevTools ウィンドウに追加できます。
- パネル は、[要素]、[ソース]、[ネットワーク] パネルなどの最上位タブです。
- サイドバー ペイン には、パネルに関連する補足 UI が表示されます。[要素] パネルの [スタイル]、[計算済みスタイル]、[イベント リスナー] ペインは、サイドバー ペインの例です。(使用している Chrome のバージョンや DevTools ウィンドウのドッキング位置によっては、サイドバー ペインの外観が画像と異なる場合があります)。
![[要素] パネルと [スタイル] サイドバー ペインが表示されている DevTools ウィンドウ。](https://developer.chrome.com/static/docs/extensions/mv2/devtools/image/devtools-window-showing-e-0c80c2293e3d4.png?hl=ja)
各パネルは独自の HTML ファイルで、他のリソース(JavaScript、CSS、画像など)を含めることができます。基本的なパネルの作成は次のようになります。
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
パネルまたはサイドバー ペインで実行される JavaScript は、DevTools ページと同じ API にアクセスできます。
[要素] パネルの基本的なサイドバー ペインの作成は次のようになります。
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
サイドバー ペインにコンテンツを表示する方法はいくつかあります。
- HTML コンテンツ。
setPageを呼び出して、ペインに表示する HTML ページを指定します。 - JSON データ。JSON オブジェクトを
setObjectに渡します。 - JavaScript 式。式を
setExpressionに渡します。DevTools は、検証対象のページのコンテキストで式を評価し、戻り値を表示します。
setObject と setExpression のどちらの場合でも、ペインには DevTools コンソールに表示される値が表示されます。ただし、setExpression では DOM 要素と任意の JavaScript オブジェクトを表示できますが、setObject では JSON オブジェクトのみがサポートされます。
拡張機能コンポーネント間の通信
以降のセクションでは、DevTools 拡張機能のさまざまなコンポーネント間の通信の一般的なシナリオについて説明します。
コンテンツ スクリプトの挿入
DevTools ページから tabs.executeScript を直接呼び出すことはできません。DevTools ページからコンテンツ スクリプトを挿入するには、検証対象のウィンドウのタブの ID を取得し、
inspectedWindow.tabId プロパティを使用してバックグラウンド ページにメッセージを送信する必要があります。バックグラウンド ページから tabs.executeScript を呼び出して、スクリプトを挿入します。
次のコード スニペットは、executeScript を使用してコンテンツ スクリプトを挿入する方法を示しています。
// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
backgroundPageConnection.onMessage.addListener(function (message) {
// Handle responses from the background page, if any
});
// Relay the tab ID to the background page
chrome.runtime.sendMessage({
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content_script.js"
});
バックグラウンド ページのコード:
// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
// assign the listener function to a variable so we can remove it later
var devToolsListener = function(message, sender, sendResponse) {
// Inject a content script into the identified tab
chrome.tabs.executeScript(message.tabId,
{ file: message.scriptToInject });
}
// add the listener
devToolsConnection.onMessage.addListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function() {
devToolsConnection.onMessage.removeListener(devToolsListener);
});
});
検証対象のウィンドウで JavaScript を評価する
inspectedWindow.eval メソッドを使用すると、
検証対象のページのコンテキストで JavaScript コードを実行できます。eval メソッドは、DevTools ページ、パネル、サイドバー ペインから呼び出すことができます。
デフォルトでは、式はページのメインフレームのコンテキストで評価されます。要素の検証(inspect(elem))、関数でのブレークポイント(debug(fn))、クリップボードへのコピー(copy())など、DevTools コマンドライン API の機能をご存知かもしれません。inspectedWindow.eval() は、DevTools コンソールで入力されたコードと同じスクリプト実行コンテキストとオプションを使用するため、eval 内でこれらの API にアクセスできます。たとえば、SOAK は要素の検証に
使用します。
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
または、inspectedWindow.eval() に useContentScriptContext: true オプションを使用して、コンテンツ スクリプトと同じコンテキストで式を評価します。useContentScriptContext: true を指定して eval を呼び出しても、コンテンツ スクリプト コンテキストは作成されないため、executeScript を呼び出すか、manifest.json ファイルでコンテンツ スクリプトを指定して、eval を呼び出す前にコンテキスト スクリプトを読み込む必要があります。
コンテキスト スクリプト コンテキストが存在する場合は、このオプションを使用して追加のコンテンツ スクリプトを挿入できます。
eval メソッドは、適切なコンテキストで使用すると強力ですが、不適切に使用すると危険です。検証対象のページの JavaScript コンテキストにアクセスする必要がない場合は、tabs.executeScript メソッドを使用します。詳細な注意事項と 2 つの方法の比較については、
inspectedWindow をご覧ください。
選択した要素をコンテンツ スクリプトに渡す
コンテンツ スクリプトは、現在選択されている要素に直接アクセスできません。ただし、
使用して実行するコードは、inspectedWindow.eval DevTools コンソールとコマンドライン API にアクセスできます。
たとえば、評価されたコードで $0 を使用して選択した要素にアクセスできます。
選択した要素をコンテンツ スクリプトに渡すには:
- 選択した要素を引数として受け取るメソッドをコンテンツ スクリプトに作成します。
-
useContentScriptContext: trueオプションを指定してinspectedWindow.evalを使用し、DevTools ページからメソッドを呼び出します。
コンテンツ スクリプトのコードは次のようになります。
function setSelectedElement(el) {
// do something with the selected element
}
DevTools ページから次のようにメソッドを呼び出します。
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
useContentScriptContext: true オプションは、式をコンテンツ スクリプトと同じコンテキストで評価する必要があることを指定するため、setSelectedElement メソッドにアクセスできます。
参照パネルの window を取得する
devtools パネルから postMessage を行うには、その window オブジェクトへの参照が必要です。
panel.onShown イベント ハンドラからパネルの iframe ウィンドウを取得します。
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
コンテンツ スクリプトから DevTools ページへのメッセージ送信
DevTools ページとコンテンツ スクリプト間のメッセージングは、バックグラウンド ページを介して間接的に行われます。
コンテンツ スクリプトにメッセージを送信する場合、バックグラウンド ページは
tabs.sendMessage メソッドを使用できます。このメソッドは、コンテンツ スクリプトの挿入で説明されているように、特定のタブのコンテンツ スクリプトにメッセージを送信します。
to Injecting a Content Script
コンテンツ スクリプトからメッセージを送信する場合、現在のタブに関連付けられている正しい DevTools ページ インスタンスにメッセージを配信する既製のメソッドはありません。 回避策として、DevTools ページでバックグラウンド ページとの長期的な接続を確立し、バックグラウンド ページでタブ ID と接続のマッピングを保持して、各メッセージを正しい接続にルーティングできます。
// background.js
var connections = {};
chrome.runtime.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
// The original connection event doesn't include the tab ID of the
// DevTools page, so we need to send it explicitly.
if (message.name == "init") {
connections[message.tabId] = port;
return;
}
// other message handling
}
// Listen to messages sent from the DevTools page
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
var tabs = Object.keys(connections);
for (var i=0, len=tabs.length; i < len; i++) {
if (connections[tabs[i]] == port) {
delete connections[tabs[i]]
break;
}
}
});
});
// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// Messages from content scripts should have sender.tab set
if (sender.tab) {
var tabId = sender.tab.id;
if (tabId in connections) {
connections[tabId].postMessage(request);
} else {
console.log("Tab not found in connection list.");
}
} else {
console.log("sender.tab not defined.");
}
return true;
});
DevTools ページ(またはパネルまたはサイドバー ペイン)は、次のように接続を確立します。
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
挿入されたスクリプトから DevTools ページへのメッセージ送信
上記のソリューションはコンテンツ スクリプトでは機能しますが、ページに直接挿入されるコード(<script> タグの追加や inspectedWindow.eval など)では別の方法が必要です。このコンテキストでは、runtime.sendMessage は想定どおりに
バックグラウンド スクリプトにメッセージを渡しません。
回避策として、挿入されたスクリプトを仲介として機能するコンテンツ スクリプトと組み合わせることができます。メッセージをコンテンツ スクリプトに渡すには、window.postMessage
API を使用します。前のセクションのバックグラウンド スクリプトを想定した例を次に示します。
// injected-script.js
window.postMessage({
greeting: 'hello there!',
source: 'my-devtools-extension'
}, '*');
// content-script.js
window.addEventListener('message', function(event) {
// Only accept messages from the same frame
if (event.source !== window) {
return;
}
var message = event.data;
// Only accept messages that we know are ours
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
これで、メッセージは挿入されたスクリプトからコンテンツ スクリプト、バックグラウンド スクリプト、そして DevTools ページへと流れます。
ここでは、2 つの代替メッセージ パッシング手法も検討できます。
DevTools の開閉を検出する
拡張機能で DevTools ウィンドウが開いているかどうかをトラッキングする必要がある場合は、バックグラウンド ページに onConnect リスナーを追加し、DevTools ページから connect を呼び出すことができます。各タブで独自の DevTools ウィンドウを開くことができるため、複数の接続イベントを受信する可能性があります。DevTools ウィンドウが開いているかどうかをトラッキングするには、次のように接続イベントと切断イベントをカウントする必要があります。
// background.js
var openCount = 0;
chrome.runtime.onConnect.addListener(function (port) {
if (port.name == "devtools-page") {
if (openCount == 0) {
alert("DevTools window opening.");
}
openCount++;
port.onDisconnect.addListener(function(port) {
openCount--;
if (openCount == 0) {
alert("Last DevTools window closing.");
}
});
}
});
DevTools ページは次のように接続を作成します。
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
DevTools 拡張機能の例
次の DevTools 拡張機能の例のソースをご覧ください。
- Polymer Devtools Extension - ホストページで実行される多くのヘルパーを使用して DOM/JS の状態をクエリし、カスタム パネルに送信します。
- React DevTools Extension - Blink のサブモジュールを使用して、DevTools UI コンポーネントを再利用します。
- Ember Inspector \- Chrome と Firefox の両方のアダプターを備えた共有拡張機能コア。
- Coquette-inspect - デバッグ エージェントが ホストページに挿入された、クリーンな React ベースの拡張機能。
- DevTools 拡張機能ギャラリーとサンプル拡張機能には、インストール、試用、学習に役立つアプリが他にもあります。
詳細
拡張機能で使用できる標準 API については、chrome.* API と ウェブ API をご覧ください。
フィードバックをお寄せください。 コメントやご提案は、API の改善に役立ちます。
例
DevTools API を使用する例については、サンプルをご覧ください。