Memperluas DevTools

Ekstensi DevTools menambahkan fitur ke Chrome DevTools dengan mengakses API ekstensi khusus DevTools melalui halaman DevTools yang ditambahkan ke ekstensi.

Diagram arsitektur yang menunjukkan halaman DevTools berkomunikasi dengan
         jendela yang diperiksa dan pekerja layanan. Service worker ditampilkan
         berkomunikasi dengan skrip konten dan mengakses API ekstensi.
         Halaman DevTools memiliki akses ke DevTools API, misalnya, membuat panel.
Arsitektur ekstensi DevTools.

API ekstensi khusus DevTools mencakup hal berikut:

Halaman DevTools

Saat jendela DevTools terbuka, ekstensi DevTools membuat instance halaman DevTools yang ada selama jendela terbuka. Halaman ini memiliki akses ke API DevTools dan API ekstensi, serta dapat melakukan hal berikut:

Halaman DevTools dapat langsung mengakses API ekstensi. Hal ini mencakup kemampuan untuk berkomunikasi dengan service worker menggunakan transfer pesan.

Membuat ekstensi DevTools

Untuk membuat halaman DevTools untuk ekstensi Anda, tambahkan kolom devtools_page di manifes ekstensi:

{
  "name": ...
  "version": "1.0",
  "devtools_page": "devtools.html",
  ...
}

Kolom devtools_page harus mengarah ke halaman HTML. Karena halaman DevTools harus bersifat lokal untuk ekstensi Anda, sebaiknya tentukan menggunakan URL relatif.

Anggota chrome.devtools API hanya tersedia untuk halaman yang dimuat dalam jendela DevTools saat jendela tersebut terbuka. Skrip konten dan halaman ekstensi lainnya tidak memiliki akses ke API ini.

Namespace browser dan ekstensi DevTools

Namespace browser yang diperkenalkan di Chrome 148 dinonaktifkan untuk ekstensi yang mendeklarasikan devtools_page. Penonaktifan berlaku untuk seluruh ekstensi — bukan hanya halaman DevTools, tetapi setiap konteks skrip tempat API ekstensi berjalan. Terus gunakan chrome.* di seluruh ekstensi ini.

Alasannya adalah kesenjangan kompatibilitas dengan webextension-polyfill. API chrome.devtools.* hanya callback—API ini belum menampilkan Promise secara native—sehingga ekstensi DevTools biasanya mengandalkan polyfill untuk membungkusnya. Polyfill melewati pembungkusan setiap kali browser ditentukan, dengan asumsi host telah melakukan pekerjaan tersebut. Jika Chrome mengaktifkan browser untuk ekstensi ini, polyfill tidak akan melakukan apa pun dan panggilan chrome.devtools.* akan berhenti menampilkan Promise. Jika browser dinonaktifkan, polyfill akan terus melakukan wrapping.

Pilihan tidak ikut yang sama juga menonaktifkan perubahan API pesan Chrome 148 lainnya untuk ekstensi ini, termasuk respons Promise di runtime.onMessage. Batasan akan dicabut setelah API DevTools mendukung Promise secara native.

Elemen UI DevTools: panel dan panel sidebar

Selain elemen UI ekstensi biasa, seperti tindakan browser, menu konteks, dan pop-up, ekstensi DevTools dapat menambahkan elemen UI ke jendela DevTools:

  • Panel adalah tab tingkat teratas, seperti panel Elements, Sources, dan Network.
  • Panel sidebar menampilkan UI tambahan yang terkait dengan panel. Panel Styles, Computed Styles, dan Event Listeners di panel Elements adalah contoh panel sidebar. Bergantung pada versi Chrome yang Anda gunakan dan tempat jendela DevTools di-dock, panel sidebar Anda mungkin terlihat seperti contoh gambar berikut:
Jendela DevTools yang menampilkan panel Elemen dan panel sidebar Gaya.
Jendela DevTools yang menampilkan panel Elements dan panel sidebar Styles.

Setiap panel adalah file HTML-nya sendiri, yang dapat menyertakan resource lain (JavaScript, CSS, gambar, dan sebagainya). Untuk membuat panel dasar, gunakan kode berikut:

chrome.devtools.panels.create("My Panel",
    "MyPanelIcon.png",
    "Panel.html",
    function(panel) {
      // code invoked on panel creation
    }
);

JavaScript yang dieksekusi di panel atau panel sidebar memiliki akses ke API yang sama dengan halaman DevTools.

Untuk membuat panel sidebar dasar, gunakan kode berikut:

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
    function(sidebar) {
        // sidebar initialization code here
        sidebar.setObject({ some_data: "Some data to show" });
});

Ada beberapa cara untuk menampilkan konten di panel sidebar:

  • Konten HTML: Panggil setPage() untuk menentukan halaman HTML yang akan ditampilkan di panel.
  • Data JSON: Teruskan objek JSON ke setObject().
  • Ekspresi JavaScript: Teruskan ekspresi ke setExpression(). DevTools mengevaluasi ekspresi dalam konteks halaman yang diperiksa, lalu menampilkan nilai yang ditampilkan.

Untuk setObject() dan setExpression(), panel menampilkan nilai sebagaimana akan muncul di konsol DevTools. Namun, setExpression() memungkinkan Anda menampilkan elemen DOM dan objek JavaScript arbitrer, sedangkan setObject() hanya mendukung objek JSON.

Berkomunikasi antar-komponen ekstensi

Bagian berikut menjelaskan beberapa cara berguna untuk memungkinkan komponen ekstensi DevTools berkomunikasi satu sama lain.

Menyuntikkan skrip konten

Untuk menyuntikkan skrip konten, gunakan scripting.executeScript():

// DevTools page -- devtools.js
chrome.scripting.executeScript({
  target: {
    tabId: chrome.devtools.inspectedWindow.tabId
  },
  files: ["content_script.js"]
});

Anda dapat mengambil ID tab jendela yang diperiksa menggunakan properti inspectedWindow.tabId.

Jika skrip konten telah disisipkan, Anda dapat menggunakan API pesan untuk berkomunikasi dengannya.

Mengevaluasi JavaScript di jendela yang diperiksa

Anda dapat menggunakan metode inspectedWindow.eval() untuk mengeksekusi kode JavaScript dalam konteks halaman yang diperiksa. Anda dapat memanggil metode eval() dari halaman DevTools, panel, atau panel sidebar.

Secara default, ekspresi dievaluasi dalam konteks frame utama halaman. inspectedWindow.eval() menggunakan konteks dan opsi eksekusi skrip yang sama dengan kode yang dimasukkan di konsol DevTools, yang memungkinkan akses ke fitur Console Utilities API DevTools saat menggunakan eval(). Misalnya, gunakan untuk memeriksa elemen skrip pertama dalam bagian <head> dokumen HTML:

chrome.devtools.inspectedWindow.eval(
  "inspect($$('head script')[0])",
  function(result, isException) { }
);

Anda juga dapat menyetel useContentScriptContext ke true saat memanggil inspectedWindow.eval() untuk mengevaluasi ekspresi dalam konteks yang sama dengan skrip konten. Untuk menggunakan opsi ini, gunakan deklarasi skrip konten statis sebelum memanggil eval(), baik dengan memanggil executeScript() atau dengan menentukan skrip konten dalam file manifest.json. Setelah konteks skrip konten dimuat, Anda juga dapat menggunakan opsi ini untuk menyuntikkan skrip konten tambahan.

Meneruskan elemen yang dipilih ke skrip konten

Skrip konten tidak memiliki akses langsung ke elemen yang saat ini dipilih. Namun, kode apa pun yang Anda jalankan menggunakan inspectedWindow.eval() memiliki akses ke konsol DevTools dan API Utilitas Konsol. Misalnya, dalam kode yang dievaluasi, Anda dapat menggunakan $0 untuk mengakses elemen yang dipilih.

Untuk meneruskan elemen yang dipilih ke skrip konten:

  1. Buat metode dalam skrip konten yang menggunakan elemen yang dipilih sebagai argumen.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Panggil metode dari halaman DevTools menggunakan inspectedWindow.eval() dengan opsi useContentScriptContext: true.

    chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
        { useContentScriptContext: true });
    

Opsi useContentScriptContext: true menentukan bahwa ekspresi harus dievaluasi dalam konteks yang sama dengan skrip konten, sehingga dapat mengakses metode setSelectedElement.

Mendapatkan window panel referensi

Untuk memanggil postMessage() dari panel devtools, Anda memerlukan referensi ke objek window-nya. Mendapatkan jendela iframe panel dari pengendali peristiwa panel.onShown:

extensionPanel.onShown.addListener(function (extPanelWindow) {
    extPanelWindow instanceof Window; // true
    extPanelWindow.postMessage( // …
});

Mengirim pesan dari skrip yang disisipkan ke halaman DevTools

Kode yang disisipkan langsung ke halaman tanpa skrip konten, termasuk dengan menambahkan tag <script> atau memanggil inspectedWindow.eval(), tidak dapat mengirim pesan ke halaman DevTools menggunakan runtime.sendMessage(). Sebagai gantinya, sebaiknya gabungkan skrip yang disisipkan dengan skrip konten yang dapat bertindak sebagai perantara, dan gunakan metode window.postMessage(). Contoh berikut menggunakan skrip latar belakang dari bagian sebelumnya:

// 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);
});

Teknik penerusan pesan alternatif lainnya dapat ditemukan di GitHub.

Mendeteksi saat DevTools dibuka dan ditutup

Untuk melacak apakah jendela DevTools terbuka, tambahkan pemroses onConnect ke pekerja layanan dan panggil connect() dari halaman DevTools. Karena setiap tab dapat membuka jendela DevTools-nya sendiri, Anda mungkin menerima beberapa peristiwa koneksi. Untuk melacak apakah ada jendela DevTools yang terbuka, hitung peristiwa connect dan disconnect seperti yang ditunjukkan dalam contoh berikut:

// 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.");
          }
      });
    }
});

Halaman DevTools membuat koneksi seperti ini:

// 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);

Contoh ekstensi DevTools

Contoh di halaman ini berasal dari halaman berikut:

  • Ekstensi Polymer Devtools - Menggunakan banyak helper yang berjalan di halaman host untuk mengkueri status DOM/JS untuk dikirim kembali ke panel kustom.
  • Ekstensi React DevTools - Menggunakan submodul perender untuk menggunakan kembali komponen UI DevTools.
  • Ember Inspector - Shared extension core dengan adapter untuk Chrome dan Firefox.
  • Coquette-inspect - Ekstensi berbasis React yang bersih dengan agen pen-debug yang disuntikkan ke halaman host.
  • Ekstensi Contoh memiliki ekstensi yang lebih berharga untuk diinstal, dicoba, dan dipelajari.

Informasi selengkapnya

Untuk mengetahui informasi tentang API standar yang dapat digunakan ekstensi, lihat chrome.* API dan web API.

Berikan masukan kepada kami Komentar dan saran Anda membantu kami meningkatkan kualitas API.

Contoh

Anda dapat menemukan contoh yang menggunakan API DevTools di Contoh.