ขยายเครื่องมือสำหรับนักพัฒนาเว็บ

ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บเพิ่มฟีเจอร์ต่างๆ ลงใน Chrome DevTools ด้วยการเข้าถึงเฉพาะเครื่องมือสำหรับนักพัฒนาเว็บ API ของส่วนขยายผ่านหน้าเครื่องมือสำหรับนักพัฒนาเว็บที่เพิ่มลงในส่วนขยาย

แผนภาพสถาปัตยกรรมแสดงหน้าเครื่องมือสำหรับนักพัฒนาเว็บที่สื่อสารกับ
         และ Service Worker Service Worker แสดงอยู่
         สื่อสารกับสคริปต์เนื้อหาและเข้าถึง API ส่วนขยาย
         หน้าเครื่องมือสำหรับนักพัฒนาเว็บมีสิทธิ์เข้าถึง API ของเครื่องมือสำหรับนักพัฒนาเว็บได้ เช่น การสร้างแผง
สถาปัตยกรรมส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ

API ส่วนขยายเฉพาะสำหรับเครื่องมือสำหรับนักพัฒนาเว็บรวมสิ่งต่อไปนี้

หน้าเครื่องมือสำหรับนักพัฒนาเว็บ

เมื่อหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดขึ้น ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บจะสร้างอินสแตนซ์ของหน้าเครื่องมือสำหรับนักพัฒนาเว็บที่ อยู่ตราบใดที่หน้าต่างเปิดอยู่ หน้านี้มีสิทธิ์เข้าถึง API ของเครื่องมือสำหรับนักพัฒนาเว็บและ API ส่วนขยาย และทำสิ่งต่อไปนี้ได้

  • สร้างและโต้ตอบกับแผงโดยใช้ API ของ devtools.panels ซึ่งรวมถึงการเพิ่มหน้าส่วนขยายอื่นๆ เป็นแผงหรือแถบด้านข้างในหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ
  • รับข้อมูลเกี่ยวกับหน้าต่างที่ตรวจสอบแล้วและประเมินโค้ดในหน้าต่างที่ตรวจสอบโดยใช้ devtools.inspectedWindow API
  • รับข้อมูลเกี่ยวกับคำขอเครือข่ายโดยใช้ devtools.network API
  • ขยายแผงโปรแกรมอัดเสียงโดยใช้ devtools.recorder API
  • ดูข้อมูลเกี่ยวกับสถานะการบันทึกของแผงประสิทธิภาพโดยใช้ devtools.performance API

หน้าเครื่องมือสำหรับนักพัฒนาเว็บเข้าถึง API ส่วนขยายได้โดยตรง ซึ่งรวมถึงความสามารถในการ เพื่อสื่อสารกับ Service Worker โดยใช้ การส่งข้อความ

สร้างส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ

หากต้องการสร้างหน้าเครื่องมือสำหรับนักพัฒนาเว็บสำหรับส่วนขยาย ให้เพิ่มช่อง devtools_page ในส่วนขยาย ไฟล์ Manifest:

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

ฟิลด์ devtools_page ต้องชี้ไปที่หน้า HTML เนื่องจากเครื่องมือสำหรับนักพัฒนาเว็บ หน้าเว็บนั้นต้องอยู่ภายในส่วนขยายของคุณ เราขอแนะนำให้ระบุโดยใช้ URL ที่เกี่ยวข้อง

สมาชิกของ chrome.devtools API ใช้ได้เฉพาะกับหน้าที่โหลดภายในเครื่องมือสำหรับนักพัฒนาเว็บเท่านั้น ขณะที่หน้าต่างนั้นเปิดอยู่ สคริปต์เนื้อหาและหน้าส่วนขยายอื่นๆ ไม่มีสิทธิ์เข้าถึง กับ API เหล่านี้

องค์ประกอบ UI ของเครื่องมือสำหรับนักพัฒนาเว็บ: แผงและแผงแถบด้านข้าง

นอกเหนือจากองค์ประกอบ UI ของส่วนขยายตามปกติ เช่น การทำงานของเบราว์เซอร์ เมนูตามบริบท และป๊อปอัป ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บสามารถเพิ่มองค์ประกอบ UI ลงในหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บได้โดยทำดังนี้

  • แผงคือแท็บระดับบนสุด เช่น แผงองค์ประกอบ แหล่งที่มา และเครือข่าย
  • แผงแถบด้านข้างจะแสดง UI เสริมที่เกี่ยวข้องกับแผง รูปแบบ รูปแบบที่คำนวณ และ แผง Listener เหตุการณ์บนแผงองค์ประกอบเป็นตัวอย่างของแผงแถบด้านข้าง ขึ้นอยู่กับ เวอร์ชัน Chrome ที่คุณใช้อยู่ และตำแหน่งของหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บอาจวางอยู่บนแท่นชาร์จ มีลักษณะเหมือนรูปภาพตัวอย่างต่อไปนี้
หน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บที่แสดงแผงองค์ประกอบและแผงแถบด้านข้างของรูปแบบ
หน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บที่แสดงแผงองค์ประกอบและแผงแถบด้านข้างของรูปแบบ

แต่ละแผงเป็นไฟล์ HTML ของตัวเอง ซึ่งอาจมีทรัพยากรอื่นๆ (JavaScript, CSS, รูปภาพ เป็นต้น เปิด) โปรดใช้โค้ดต่อไปนี้เพื่อสร้างแผงพื้นฐาน

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

JavaScript ที่เรียกใช้ในแผงหรือแผงแถบด้านข้างมีสิทธิ์เข้าถึง 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() แผงจะแสดงค่าตามที่จะปรากฏในคอลัมน์ คอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ แต่ setExpression() ให้คุณแสดงองค์ประกอบ DOM และ JavaScript ที่กำหนดเองได้ แต่ setObject() รองรับเฉพาะออบเจ็กต์ JSON เท่านั้น

สื่อสารระหว่างคอมโพเนนต์ส่วนขยาย

ส่วนต่อไปนี้จะอธิบายวิธีที่เป็นประโยชน์ในการอนุญาตให้คอมโพเนนต์ส่วนขยายของเครื่องมือสำหรับนักพัฒนาเว็บดำเนินการต่อไปนี้ได้ สื่อสารกัน

แทรกสคริปต์เนื้อหา

หากต้องการแทรกสคริปต์เนื้อหา ให้ใช้ scripting.executeScript() ดังนี้

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

คุณสามารถเรียกข้อมูลรหัสแท็บของหน้าต่างที่ตรวจสอบได้โดยใช้ inspectedWindow.tabId

หากมีการแทรกสคริปต์เนื้อหาแล้ว คุณสามารถใช้ API การรับส่งข้อความเพื่อ สื่อสารกับอุปกรณ์นั้นๆ

ประเมิน JavaScript ในหน้าต่างที่ตรวจสอบ

คุณใช้เมธอด inspectedWindow.eval() เพื่อเรียกใช้ JavaScript ได้ ในบริบทของหน้าเว็บที่ตรวจสอบ คุณสามารถเรียกใช้เมธอด eval() จากหน้าเครื่องมือสำหรับนักพัฒนาเว็บ หรือแผงแถบด้านข้าง

โดยค่าเริ่มต้น นิพจน์จะได้รับการประเมินในบริบทของเฟรมหลักของหน้า inspectedWindow.eval() ใช้บริบทและตัวเลือกการเรียกใช้สคริปต์เดียวกันกับโค้ด ที่ป้อนในคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ ซึ่งอนุญาตให้เข้าถึงเครื่องมือสำหรับนักพัฒนาเว็บยูทิลิตีคอนโซล API เมื่อใช้ eval() ตัวอย่างเช่น SOAK ใช้เพื่อตรวจสอบองค์ประกอบ ดังนี้

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

คุณยังตั้งค่า useContentScriptContext เป็น true เมื่อโทรหา inspectedWindow.eval() ได้ด้วย ประเมินนิพจน์ในบริบทเดียวกับสคริปต์เนื้อหา หากต้องการใช้ตัวเลือกนี้ ให้ใช้การประกาศสคริปต์เนื้อหาแบบคงที่ก่อนเรียกใช้ eval() โดยจะเรียกใช้ executeScript() หรือระบุเนื้อหาก็ได้ ในไฟล์ manifest.json หลังจากโหลดบริบทสคริปต์บริบทแล้ว คุณสามารถใช้ตัวเลือกนี้เพื่อ แทรกสคริปต์เนื้อหาเพิ่มเติม

ส่งต่อองค์ประกอบที่เลือกไปยังสคริปต์เนื้อหา

สคริปต์เนื้อหาไม่มีสิทธิ์เข้าถึงองค์ประกอบที่เลือกในปัจจุบันโดยตรง อย่างไรก็ตาม โค้ดที่คุณ เรียกใช้โดยใช้ inspectedWindow.eval() มีสิทธิ์เข้าถึงเครื่องมือสำหรับนักพัฒนาเว็บ Console และ Console Utilities API เช่น ในโค้ดที่ประเมิน คุณจะใช้ $0 เพื่อเข้าถึง องค์ประกอบที่เลือก

วิธีส่งองค์ประกอบที่เลือกไปยังสคริปต์เนื้อหา

  1. สร้างเมธอดในสคริปต์เนื้อหาเพื่อนำองค์ประกอบที่เลือกเป็นอาร์กิวเมนต์

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. เรียกใช้เมธอดจากหน้าเครื่องมือสำหรับนักพัฒนาเว็บโดยใช้ inspectedWindow.eval() ที่มีตัวเลือก useContentScriptContext: true

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

ตัวเลือก useContentScriptContext: true ระบุว่าต้องมีการประเมินนิพจน์ใน บริบทเดียวกับสคริปต์เนื้อหา เพื่อให้สามารถเข้าถึงเมธอด setSelectedElement

รับwindowของแผงอ้างอิง

หากต้องการเรียกใช้ postMessage() จากแผงเครื่องมือสำหรับนักพัฒนาเว็บ คุณจะต้องอ้างอิงออบเจ็กต์ window รับ หน้าต่าง iframe ของแผงจากเครื่องจัดการเหตุการณ์ panel.onShown

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

ส่งข้อความจากสคริปต์ที่แทรกไว้ไปยังหน้าเครื่องมือสำหรับนักพัฒนาเว็บ

โค้ดที่แทรกลงในหน้าเว็บโดยตรงโดยไม่มีสคริปต์เนื้อหา ซึ่งรวมถึงการเพิ่ม <script> แท็กหรือการเรียก inspectedWindow.eval() จะไม่สามารถส่งข้อความไปยัง หน้าเครื่องมือสำหรับนักพัฒนาเว็บที่ใช้ runtime.sendMessage() เราขอแนะนำให้คุณ ที่รวมสคริปต์ที่คุณแทรกไว้กับสคริปต์เนื้อหาซึ่งทำหน้าที่เป็นสื่อกลางและใช้ เมธอด 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

ตรวจจับเวลาเปิดและปิดเครื่องมือสำหรับนักพัฒนาเว็บ

หากต้องการติดตามว่าหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่หรือไม่ ให้เพิ่ม Listener onConnect ไปยัง Service Worker และเรียกใช้ connect() จากหน้าเครื่องมือสำหรับนักพัฒนาเว็บ เพราะ แต่ละแท็บสามารถเปิดหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บของตัวเองได้ และคุณอาจได้รับเหตุการณ์การเชื่อมต่อหลายรายการ หากต้องการติดตามว่าหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่หรือไม่ ให้นับเหตุการณ์การเชื่อมต่อและยกเลิกการเชื่อมต่อตามที่แสดง ในตัวอย่างต่อไปนี้

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

ตัวอย่างส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ

ตัวอย่างในหน้านี้มาจากหน้าต่อไปนี้

  • ส่วนขยาย Polymer Devtools - ใช้ตัวช่วยต่างๆ ที่ทำงานอยู่ในหน้าโฮสต์เพื่อค้นหา สถานะ DOM/JS ที่จะส่งกลับไปยังแผงที่กำหนดเอง
  • รีแอ็กชันส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ - ใช้โมดูลย่อยของโหมดแสดงภาพเพื่อใช้ UI ของเครื่องมือสำหรับนักพัฒนาเว็บซ้ำ คอมโพเนนต์
  • Ember Inspector - แกนส่วนขยายที่ใช้ร่วมกันกับอะแดปเตอร์สำหรับทั้ง Chrome และ Firefox
  • Coquette-inspect - ส่วนขยายที่ใช้ React ที่ดูสะอาดตาซึ่งมีการแทรก Agent การแก้ไขข้อบกพร่อง ลงในหน้าโฮสต์
  • ส่วนขยายตัวอย่างมีส่วนขยายที่คุ้มค่ากว่าในการติดตั้ง ทดลองใช้ และเรียนรู้ จาก

ข้อมูลเพิ่มเติม

สำหรับข้อมูลเกี่ยวกับ API มาตรฐานที่ส่วนขยายสามารถใช้ได้ โปรดดู chrome* API และเว็บ API

แสดงความคิดเห็นให้เราทราบ ความคิดเห็นและคำแนะนำของคุณจะช่วยเราปรับปรุง API ให้ดียิ่งขึ้น

ตัวอย่าง

ดูตัวอย่างที่ใช้ API ของเครื่องมือสำหรับนักพัฒนาเว็บได้ในตัวอย่าง