DevTools 拡張機能は、拡張機能に追加された DevTools ページから DevTools 固有の拡張機能 API にアクセスして、Chrome DevTools に機能を追加します。
DevTools 固有の拡張機能 API には、次のものがあります。
DevTools ページ
DevTools ウィンドウが開くと、DevTools 拡張機能は、ウィンドウが開いている間存在する DevTools ページのインスタンスを作成します。このページは DevTools API と拡張機能 API にアクセスでき、次のことができます。
devtools.panelsAPI を使用してパネルを作成し、操作します。これには、他の拡張機能ページをパネルまたはサイドバーとして DevTools ウィンドウに追加することも含まれます。- `devtools.inspectedWindow` API を使用して、検査対象のウィンドウに関する情報を取得し、検査対象のウィンドウでコードを評価します。
devtools.inspectedWindow devtools.networkAPI を使用して、ネットワーク リクエストに関する情報を取得します。- レコーダー パネルを、
devtools.recorderAPI を使用して拡張します。 devtools.performanceAPI を使用して、パフォーマンス パネルの記録ステータスに関する情報を取得します。
DevTools ページは、拡張機能 API に直接アクセスできます。これには、Service Worker と 通信するために メッセージ パッシングを使用できることも含まれます。
DevTools 拡張機能を作成する
拡張機能の DevTools ページを作成するには、拡張機能マニフェストに devtools_page フィールドを追加します。
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
devtools_page フィールドは HTML ページを指している必要があります。DevTools ページは拡張機能に対してローカルである必要があるため、相対 URL を使用して指定することをおすすめします。
chrome.devtools API のメンバーは、DevTools ウィンドウが開いている間、そのウィンドウ内に読み込まれたページでのみ使用できます。コンテンツ スクリプトや他の拡張機能ページは、これらの API にアクセスできません。
ブラウザの名前空間と DevTools 拡張機能
Chrome 148 で導入された browser 名前空間
は、
devtools_page を宣言する拡張機能では無効になっています。オプトアウトは、DevTools ページだけでなく、拡張機能 API が実行されるすべてのスクリプト コンテキストなど、拡張機能全体に適用されます。これらの拡張機能では、引き続き chrome.* を使用してください。
これは、
webextension-polyfillとの互換性の問題が原因です。
chrome.devtools.* API はコールバックのみで、ネイティブで Promise を返さないため、DevTools 拡張機能は通常、polyfill を使用してラップします。polyfill は、browser が定義されている場合は常にラップをスキップし、ホストがすでに処理を完了していると想定します。Chrome がこれらの拡張機能で browser を有効にすると、polyfill は no-op になり、chrome.devtools.* 呼び出しは Promise を返さなくなります。browser を無効にすると、polyfill は引き続きラップできます。
同じオプトアウトにより、これらの拡張機能に対する Chrome 148 の他のメッセージング API の変更も無効になります。これには、Promise responses in runtime.onMessageが含まれます。この制限は、DevTools API がネイティブで Promise をサポートすると解除されます。
DevTools UI 要素: パネルとサイドバー ペイン
ブラウザ アクション、コンテキスト メニュー、ポップアップなど、通常の拡張機能 UI 要素に加えて、DevTools 拡張機能では UI 要素を DevTools ウィンドウに追加できます。
- パネルは、[要素]、[ソース]、[ネットワーク] パネルなどの最上位タブです。
- サイドバー ペインには、パネルに関連する補足 UI が表示されます。[要素] パネルの [スタイル]、[計算済みスタイル]、[イベント リスナー] ペインは、サイドバー ペインの例です。使用している Chrome のバージョンと DevTools ウィンドウのドッキング位置によっては、サイドバー ペインが次の例の画像のように表示されることがあります。
各パネルは独自の 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 拡張機能コンポーネントが相互に通信できるようにするための便利な方法について説明します。
コンテンツ スクリプトを挿入する
コンテンツ スクリプトを挿入するには、scripting.executeScript() を使用します。
// DevTools page -- devtools.js
chrome.scripting.executeScript({
target: {
tabId: chrome.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
検査対象のウィンドウのタブ ID は、
inspectedWindow.tabId プロパティを使用して取得できます。
コンテンツ スクリプトがすでに挿入されている場合は、メッセージング API を使用して通信できます。
検査対象のウィンドウで JavaScript を評価する
inspectedWindow.eval() メソッドを使用すると、検査対象のページのコンテキストで JavaScript
コードを実行できます。eval() メソッドは、DevTools ページ、パネル、サイドバー ペインから呼び出すことができます。
デフォルトでは、式はページのメインフレームのコンテキストで評価されます。
inspectedWindow.eval() は、DevTools コンソールに入力されたコード
と同じスクリプト実行コンテキストとオプションを使用します。これにより、DevTools Console Utilities
API 機能に eval() を使用するときにアクセスできます。たとえば、これを使用して HTML ドキュメントの <head> セクション内の最初のスクリプト要素を検査します。
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
inspectedWindow.eval() を呼び出すときに useContentScriptContext を true に設定して、コンテンツ スクリプトと同じコンテキストで式を評価することもできます。このオプションを使用するには、eval() を呼び出す前に 静的コンテンツ スクリプト宣言 を使用します。これを行うには、executeScript() を呼び出すか、manifest.json ファイルで content
script を指定します。コンテンツ スクリプト コンテキストが読み込まれたら、このオプションを使用して追加のコンテンツ スクリプトを挿入することもできます。
選択した要素をコンテンツ スクリプトに渡す
コンテンツ スクリプトは、現在選択されている要素に直接アクセスできません。ただし、inspectedWindow.eval() を使用して実行するコードは、DevTools コンソールと Console Utilities API にアクセスできます。たとえば、評価されたコードで $0 を使用して、選択した要素にアクセスできます。
選択した要素をコンテンツ スクリプトに渡すには:
選択した要素を引数として受け取るメソッドをコンテンツ スクリプトに作成します。
function setSelectedElement(el) { // do something with the selected element }useContentScriptContext: trueオプションを指定してinspectedWindow.eval()を使用し、DevTools ページからメソッドを呼び出します。chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
useContentScriptContext: true オプションは、式をコンテンツ スクリプトと同じコンテキストで評価する必要があることを指定するため、setSelectedElement メソッドにアクセスできます。
リファレンス パネルの window を取得する
devtools パネルから postMessage() を呼び出すには、その window オブジェクトへの参照が必要です。
パネルの iframe ウィンドウを panel.onShown イベント ハンドラから取得します。
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
挿入されたスクリプトから DevTools ページにメッセージを送信する
コンテンツ スクリプトなしでページに直接挿入されたコード(<script>
タグの追加や inspectedWindow.eval() の呼び出しなど)は、
DevTools ページに runtime.sendMessage() を使用してメッセージを送信できません。代わりに、挿入されたスクリプトを仲介として機能するコンテンツ スクリプトと組み合わせて、
the window.postMessage() メソッドを使用することをおすすめします。次の例では、前のセクションのバックグラウンド スクリプトを使用しています。
// 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. Note that this is not foolproof
// and the page can easily spoof messages if it wants to.
if (typeof message !== 'object' || message === null ||
message.source !== 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
他の代替メッセージ パッシング手法については、GitHub をご覧ください。
DevTools の開閉を検出する
DevTools ウィンドウが開いているかどうかをトラッキングするには、onConnect リスナー を Service Worker に追加し、DevTools ページから connect() を呼び出します。各タブで独自の DevTools ウィンドウを開くことができるため、複数の connect イベントを受信する可能性があります。 DevTools ウィンドウが開いているかどうかをトラッキングするには、次の例に示すように、connect イベントと disconnect イベントをカウントします。
// 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 service worker
const serviceWorkerConnection = chrome.runtime.connect({
name: "devtools-page"
});
// Send a periodic heartbeat to keep the port open.
setInterval(() => {
port.postMessage("heartbeat");
}, 15000);
DevTools 拡張機能の例
このページの例は、次のページから引用しています。
- Polymer Devtools Extension - ホストページで実行される多くのヘルパーを使用して DOM/JS の状態をクエリし、カスタム パネルに返します。
- React DevTools Extension - レンダラ サブモジュールを使用して DevTools UI コンポーネントを再利用します。
- Ember Inspector \- Chrome と Firefox の両方のアダプターを備えた共有拡張機能コア。
- Coquette-inspect - デバッグ エージェントがホストページに挿入された、クリーンな React ベースの拡張機能。
- サンプル拡張機能には、インストール、試用、学習 に役立つ拡張機能が他にもあります。
詳細
拡張機能で使用できる標準 API については、chrome.* API と ウェブ API をご覧ください。
フィードバックをお寄せください。 コメントやご提案は、API の改善に役立ちます。
例
DevTools API を使用する例については、サンプルをご覧ください。