ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บจะเพิ่มฟีเจอร์ลงในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome โดยการเข้าถึง API ของส่วนขยายที่เฉพาะเจาะจงของเครื่องมือสำหรับนักพัฒนาเว็บผ่านหน้าเครื่องมือสำหรับนักพัฒนาเว็บที่เพิ่มลงในส่วนขยาย
API ของส่วนขยายที่เฉพาะเจาะจงของเครื่องมือสำหรับนักพัฒนาเว็บมีดังนี้
หน้าเครื่องมือสำหรับนักพัฒนาเว็บ
เมื่อหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดขึ้น ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บจะสร้างอินสแตนซ์ของหน้าเครื่องมือสำหรับนักพัฒนาเว็บ ซึ่งจะคงอยู่ตราบใดที่หน้าต่างเปิดอยู่ หน้านี้มีสิทธิ์เข้าถึง API ของเครื่องมือสำหรับนักพัฒนาเว็บและ API ของส่วนขยาย และสามารถทำสิ่งต่อไปนี้ได้
- สร้างและโต้ตอบกับแผงโดยใช้ API
devtools.panelsซึ่งรวมถึงการเพิ่มหน้าส่วนขยายอื่นๆ เป็นแผงหรือแถบด้านข้างลงในหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ - รับข้อมูลเกี่ยวกับหน้าต่างที่ตรวจสอบและประเมินโค้ดในหน้าต่างที่ตรวจสอบโดยใช้
devtools.inspectedWindowAPI - รับข้อมูลเกี่ยวกับคำขอเครือข่ายโดยใช้
devtools.networkAPI - ขยายแผงเครื่องบันทึกโดยใช้ API
devtools.recorder - รับข้อมูลเกี่ยวกับสถานะการบันทึกของ แผงประสิทธิภาพ โดยใช้
devtools.performanceAPI
หน้าเครื่องมือสำหรับนักพัฒนาเว็บสามารถเข้าถึง API ของส่วนขยายได้โดยตรง ซึ่งรวมถึงความสามารถ ในการสื่อสารกับ Service Worker โดยใช้ การส่งข้อความ
สร้างส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ
หากต้องการสร้างหน้าเครื่องมือสำหรับนักพัฒนาเว็บสำหรับส่วนขยาย ให้เพิ่มช่อง devtools_page ในไฟล์ Manifest ของส่วนขยาย
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
ช่อง devtools_page ต้องชี้ไปยังหน้า HTML เนื่องจากหน้าเครื่องมือสำหรับนักพัฒนาเว็บต้องอยู่ในส่วนขยายของคุณ เราจึงขอแนะนำให้ระบุโดยใช้ URL สัมพัทธ์
สมาชิกของ API chrome.devtools จะใช้ได้เฉพาะกับหน้าที่โหลดภายในหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บขณะที่หน้าต่างนั้นเปิดอยู่ สคริปต์เนื้อหาและหน้าส่วนขยายอื่นๆ จะไม่มีสิทธิ์เข้าถึง API เหล่านี้
เนมสเปซของเบราว์เซอร์และส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ
ใน Chrome เวอร์ชัน 152 ขึ้นไป ส่วนขยายที่มีหน้าเครื่องมือสำหรับนักพัฒนาเว็บสามารถใช้เนมสเปซ browser ได้
ใน Chrome เวอร์ชันเก่ากว่า 152 ระบบจะปิดเนมสเปซ browser
สำหรับส่วนขยายที่ประกาศ
devtools_page การเลือกไม่ใช้มีผลกับส่วนขยายทั้งหมด ไม่ใช่แค่หน้าเครื่องมือสำหรับนักพัฒนาเว็บ แต่รวมถึงบริบทสคริปต์ทั้งหมดที่ API ของส่วนขยายทำงาน
เหตุผลคือช่องว่างด้านความเข้ากันได้กับ
webextension-polyfill
API chrome.devtools.* ก่อน Chrome 152 เป็นแบบใช้ Callback เท่านั้น ซึ่งไม่ได้แสดงผล Promise โดยกำเนิด ดังนั้นส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บจึงมักจะใช้ polyfill เพื่อห่อหุ้ม API เหล่านี้ polyfill จะข้ามการห่อหุ้มทุกครั้งที่กำหนด browser โดยถือว่าโฮสต์ได้ดำเนินการแล้ว หาก Chrome เปิดใช้ browser สำหรับส่วนขยายเหล่านี้ polyfill จะไม่ดำเนินการใดๆ และการเรียก chrome.devtools.* จะหยุดแสดงผล Promise การปิด browser ไว้จะทำให้ polyfill ห่อหุ้มต่อไป
การเลือกไม่ใช้แบบเดียวกันนี้ยังปิดใช้การเปลี่ยนแปลง API การรับส่งข้อความอื่นๆ ของ Chrome 148
สำหรับส่วนขยายเหล่านี้ด้วย ซึ่งรวมถึง
การตอบกลับ Promise ใน runtime.onMessage
ข้อจำกัดนี้ถูกยกเลิกเมื่อ API ของเครื่องมือสำหรับนักพัฒนาเว็บรองรับ Promise โดยกำเนิด
องค์ประกอบ UI ของเครื่องมือสำหรับนักพัฒนาเว็บ: แผงและบานหน้าต่างแถบด้านข้าง
นอกเหนือจากองค์ประกอบ UI ของส่วนขยายทั่วไป เช่น การดำเนินการของเบราว์เซอร์ เมนูบริบท และป๊อปอัปแล้ว ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บยังเพิ่มองค์ประกอบ UI ลงในหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บได้ด้วย
- แผง คือแท็บระดับบนสุด เช่น แผงองค์ประกอบ แหล่งที่มา และเครือข่าย
- บานหน้าต่างแถบด้านข้าง จะแสดง UI เสริมที่เกี่ยวข้องกับแผง บานหน้าต่างรูปแบบ รูปแบบที่คำนวณแล้ว และตัวฟังเหตุการณ์ในแผงองค์ประกอบเป็นตัวอย่างของบานหน้าต่างแถบด้านข้าง บานหน้าต่างแถบด้านข้างอาจมีลักษณะดังรูปภาพตัวอย่างต่อไปนี้ ทั้งนี้ขึ้นอยู่กับเวอร์ชันของ 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()เครื่องมือสำหรับนักพัฒนาเว็บจะประเมินนิพจน์ในบริบทของหน้าที่ตรวจสอบ แล้วแสดงค่าที่แสดงผล
สำหรับทั้ง 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() เช่น ใช้เพื่อตรวจสอบ
องค์ประกอบสคริปต์แรกภายในส่วน <head> ของเอกสาร HTML
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
นอกจากนี้ คุณยังตั้งค่า useContentScriptContext เป็น true เมื่อเรียก inspectedWindow.eval() เพื่อประเมินนิพจน์ในบริบทเดียวกับสคริปต์เนื้อหาได้ด้วย หากต้องการใช้ตัวเลือกนี้ ให้ใช้การประกาศสคริปต์เนื้อหาแบบคงที่ก่อนเรียก eval() โดยเรียก executeScript() หรือระบุสคริปต์เนื้อหา
ในไฟล์ manifest.json หลังจากโหลดบริบทสคริปต์เนื้อหาแล้ว คุณยังใช้ตัวเลือกนี้เพื่อแทรกสคริปต์เนื้อหาเพิ่มเติมได้ด้วย
ส่งองค์ประกอบที่เลือกไปยังสคริปต์เนื้อหา
สคริปต์เนื้อหาไม่มีสิทธิ์เข้าถึงองค์ประกอบที่เลือกในปัจจุบันโดยตรง อย่างไรก็ตาม โค้ดที่คุณ
เรียกใช้โดยใช้ inspectedWindow.eval() มีสิทธิ์เข้าถึงคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ
และ API ของยูทิลิตีคอนโซล เช่น ในโค้ดที่ประเมินแล้ว คุณสามารถใช้ $0 เพื่อเข้าถึงองค์ประกอบที่เลือก
วิธีส่งองค์ประกอบที่เลือกไปยังสคริปต์เนื้อหา
สร้างเมธอดในสคริปต์เนื้อหาที่รับองค์ประกอบที่เลือกเป็นอาร์กิวเมนต์
function setSelectedElement(el) { // do something with the selected element }เรียกเมธอดจากหน้าเครื่องมือสำหรับนักพัฒนาเว็บโดยใช้
inspectedWindow.eval()พร้อมตัวเลือกuseContentScriptContext: truechrome.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
ตรวจหาเมื่อเครื่องมือสำหรับนักพัฒนาเว็บเปิดและปิด
หากต้องการติดตามว่าหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่หรือไม่ ให้เพิ่มตัวฟัง onConnect ลงใน Service Worker และเรียก connect() จากหน้าเครื่องมือสำหรับนักพัฒนาเว็บ เนื่องจากแต่ละแท็บสามารถเปิดหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บของตัวเองได้ คุณจึงอาจได้รับเหตุการณ์ connect หลายรายการ หากต้องการติดตามว่าหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่หรือไม่ ให้นับเหตุการณ์ 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.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 - ใช้ผู้ช่วยจำนวนมากที่ทำงานในหน้าโฮสต์เพื่อค้นหาสถานะ DOM/JS เพื่อส่งกลับไปยังแผงที่กำหนดเอง
- ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บของ React - ใช้โมดูลย่อยของตัวแสดงผลเพื่อนำคอมโพเนนต์ UI ของเครื่องมือสำหรับนักพัฒนาเว็บกลับมาใช้ซ้ำ
- Ember Inspector - แชร์คอร์ส่วนขยายกับอะแดปเตอร์สำหรับทั้ง Chrome และ Firefox
- Coquette-inspect - ส่วนขยายที่ใช้ React อย่างหมดจดพร้อม Agent การดีบั๊กที่แทรก ลงในหน้าโฮสต์
- ส่วนขยายตัวอย่างมีส่วนขยายที่คุ้มค่ากว่าให้ติดตั้ง ลองใช้ และเรียนรู้ จาก
ข้อมูลเพิ่มเติม
ดูข้อมูลเกี่ยวกับ API มาตรฐานที่ส่วนขยายใช้ได้ที่ chrome.* API และ Web API
ส่งความคิดเห็นถึงเรา ความคิดเห็นและข้อเสนอแนะของคุณช่วยให้เราปรับปรุง API ได้
ตัวอย่าง
ดูตัวอย่างที่ใช้ API ของเครื่องมือสำหรับนักพัฒนาเว็บได้ใน ตัวอย่าง