Tiện ích DevTools thêm các tính năng vào Công cụ của Chrome cho nhà phát triển bằng cách truy cập vào các API tiện ích dành riêng cho DevTools thông qua một trang DevTools được thêm vào tiện ích.
Các API tiện ích dành riêng cho Công cụ cho nhà phát triển bao gồm:
Trang Công cụ cho nhà phát triển
Khi một cửa sổ Công cụ cho nhà phát triển mở ra, một tiện ích Công cụ cho nhà phát triển sẽ tạo một phiên bản của trang Công cụ cho nhà phát triển. Phiên bản này sẽ tồn tại cho đến khi cửa sổ đó mở. Trang này có quyền truy cập vào các API của Công cụ cho nhà phát triển và API tiện ích, đồng thời có thể làm những việc sau:
- Tạo và tương tác với các bảng điều khiển bằng cách sử dụng API
devtools.panels, bao gồm cả việc thêm các trang tiện ích khác làm bảng điều khiển hoặc thanh bên vào cửa sổ Công cụ cho nhà phát triển. - Nhận thông tin về cửa sổ được kiểm tra và đánh giá mã trong cửa sổ được kiểm tra bằng cách sử dụng API
devtools.inspectedWindow. - Nhận thông tin về các yêu cầu mạng bằng cách sử dụng API
devtools.network. - Mở rộng bảng điều khiển Trình ghi bằng cách sử dụng các API
devtools.recorder. - Nhận thông tin về trạng thái ghi của bảng điều khiển Hiệu suất bằng cách sử dụng API
devtools.performance.
Trang Công cụ cho nhà phát triển có thể truy cập trực tiếp vào các API tiện ích. Điều này bao gồm cả việc có thể giao tiếp với trình chạy dịch vụ bằng cách sử dụng truyền thông báo.
Tạo một tiện ích Công cụ cho nhà phát triển
Để tạo một trang Công cụ cho nhà phát triển cho tiện ích, hãy thêm trường devtools_page vào tệp kê khai tiện ích:
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
Trường devtools_page phải trỏ đến một trang HTML. Vì trang Công cụ cho nhà phát triển phải nằm trên máy của tiện ích, nên bạn nên chỉ định trang này bằng một URL tương đối.
Các thành phần của API chrome.devtools chỉ có sẵn cho những trang được tải trong cửa sổ Công cụ cho nhà phát triển khi cửa sổ đó đang mở. Tập lệnh nội dung và các trang tiện ích khác không có quyền truy cập vào các API này.
Không gian tên của trình duyệt và các tiện ích của Công cụ cho nhà phát triển
Không gian tên browser được giới thiệu trong Chrome 148 sẽ bị tắt đối với những tiện ích khai báo devtools_page. Lựa chọn không tham gia áp dụng cho toàn bộ tiện ích, chứ không chỉ riêng trang Công cụ cho nhà phát triển, mà còn cho mọi ngữ cảnh tập lệnh nơi các API tiện ích chạy. Tiếp tục sử dụng chrome.* trong suốt quá trình sử dụng các tiện ích này.
Lý do là do có một khoảng trống về khả năng tương thích với webextension-polyfill.
Các API chrome.devtools.* chỉ có lệnh gọi lại (chưa trả về Lời hứa theo cách tự nhiên) nên các tiện ích DevTools thường dựa vào polyfill để bao bọc các API này. Polyfill bỏ qua việc bao bọc bất cứ khi nào browser được xác định, giả sử máy chủ lưu trữ đã thực hiện công việc. Nếu Chrome bật browser cho các tiện ích này, thì polyfill sẽ không hoạt động và các lệnh gọi chrome.devtools.* sẽ ngừng trả về Lời hứa. Nếu bạn tắt browser, polyfill sẽ tiếp tục bao bọc.
Lựa chọn không sử dụng này cũng sẽ tắt các thay đổi khác về API nhắn tin của Chrome 148 cho những tiện ích này, bao gồm cả phản hồi Promise trong runtime.onMessage.
Quy tắc hạn chế này sẽ được dỡ bỏ sau khi các API của Công cụ cho nhà phát triển hỗ trợ Promise một cách tự nhiên.
Các phần tử trên giao diện người dùng của Công cụ cho nhà phát triển: bảng điều khiển và ngăn bên
Ngoài các phần tử giao diện người dùng tiện ích thông thường, chẳng hạn như thao tác trên trình duyệt, trình đơn theo bối cảnh và cửa sổ bật lên, tiện ích DevTools có thể thêm các phần tử giao diện người dùng vào cửa sổ DevTools:
- Bảng điều khiển là một thẻ cấp cao nhất, chẳng hạn như bảng điều khiển Phần tử, Nguồn và Mạng.
- Ngăn bên trình bày giao diện người dùng bổ sung liên quan đến một bảng điều khiển. Các ngăn Styles (Kiểu), Computed Styles (Kiểu đã tính toán) và Event Listeners (Trình nghe sự kiện) trên bảng Elements (Phần tử) là ví dụ về các ngăn bên. Tuỳ thuộc vào phiên bản Chrome mà bạn đang dùng và vị trí gắn cửa sổ DevTools, các ngăn bên có thể trông giống như hình ảnh ví dụ sau:
Mỗi bảng điều khiển là một tệp HTML riêng, có thể bao gồm các tài nguyên khác (JavaScript, CSS, hình ảnh, v.v.). Để tạo một bảng điều khiển cơ bản, hãy dùng mã sau:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript được thực thi trong một bảng điều khiển hoặc ngăn bên có quyền truy cập vào cùng một API như trang Công cụ cho nhà phát triển.
Để tạo một ngăn bên cơ bản, hãy dùng mã sau:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
Có một số cách để hiển thị nội dung trong ngăn bên:
- Nội dung HTML: Gọi
setPage()để chỉ định một trang HTML cần hiển thị trong ngăn. - Dữ liệu JSON: Truyền một đối tượng JSON đến
setObject(). - Biểu thức JavaScript: Truyền một biểu thức đến
setExpression(). Công cụ cho nhà phát triển đánh giá biểu thức trong bối cảnh của trang được kiểm tra, sau đó hiển thị giá trị trả về.
Đối với cả setObject() và setExpression(), ngăn này sẽ hiển thị giá trị như giá trị xuất hiện trong bảng điều khiển Công cụ cho nhà phát triển. Tuy nhiên, setExpression() cho phép bạn hiển thị các phần tử DOM và các đối tượng JavaScript tuỳ ý, trong khi setObject() chỉ hỗ trợ các đối tượng JSON.
Giao tiếp giữa các thành phần của tiện ích
Các phần sau đây mô tả một số cách hữu ích để cho phép các thành phần tiện ích của Công cụ cho nhà phát triển giao tiếp với nhau.
Chèn tập lệnh nội dung
Để chèn một tập lệnh nội dung, hãy sử dụng scripting.executeScript():
// DevTools page -- devtools.js
chrome.scripting.executeScript({
target: {
tabId: chrome.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
Bạn có thể truy xuất mã nhận dạng thẻ của cửa sổ được kiểm tra bằng cách sử dụng thuộc tính inspectedWindow.tabId.
Nếu một tập lệnh nội dung đã được chèn, bạn có thể sử dụng API nhắn tin để giao tiếp với tập lệnh đó.
Đánh giá JavaScript trong cửa sổ được kiểm tra
Bạn có thể sử dụng phương thức inspectedWindow.eval() để thực thi mã JavaScript trong bối cảnh của trang được kiểm tra. Bạn có thể gọi phương thức eval() từ trang, bảng điều khiển hoặc ngăn bên của Công cụ cho nhà phát triển.
Theo mặc định, biểu thức được đánh giá trong bối cảnh của khung chính của trang.
inspectedWindow.eval() sử dụng cùng một ngữ cảnh và các lựa chọn thực thi tập lệnh như mã đã nhập trong bảng điều khiển Công cụ cho nhà phát triển, cho phép truy cập vào các tính năng API Tiện ích bảng điều khiển của Công cụ cho nhà phát triển khi sử dụng eval(). Ví dụ: sử dụng nó để kiểm tra phần tử tập lệnh đầu tiên trong phần <head> của tài liệu HTML:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
Bạn cũng có thể đặt useContentScriptContext thành true khi gọi inspectedWindow.eval() để đánh giá biểu thức trong cùng một ngữ cảnh với tập lệnh nội dung. Để sử dụng lựa chọn này, hãy dùng khai báo tập lệnh nội dung tĩnh trước khi gọi eval(), bằng cách gọi executeScript() hoặc chỉ định một tập lệnh nội dung trong tệp manifest.json. Sau khi tải bối cảnh tập lệnh nội dung, bạn cũng có thể dùng lựa chọn này để chèn thêm tập lệnh nội dung.
Truyền phần tử đã chọn đến một tập lệnh nội dung
Tập lệnh nội dung không có quyền truy cập trực tiếp vào phần tử hiện được chọn. Tuy nhiên, mọi mã bạn thực thi bằng inspectedWindow.eval() đều có quyền truy cập vào bảng điều khiển DevTools và API Tiện ích bảng điều khiển. Ví dụ: trong mã được đánh giá, bạn có thể sử dụng $0 để truy cập vào phần tử đã chọn.
Cách truyền phần tử đã chọn đến một tập lệnh nội dung:
Tạo một phương thức trong tập lệnh nội dung nhận phần tử đã chọn làm đối số.
function setSelectedElement(el) { // do something with the selected element }Gọi phương thức từ trang Công cụ cho nhà phát triển bằng cách sử dụng
inspectedWindow.eval()với lựa chọnuseContentScriptContext: true.chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
Lựa chọn useContentScriptContext: true chỉ định rằng biểu thức phải được đánh giá trong cùng một ngữ cảnh với tập lệnh nội dung, vì vậy, biểu thức có thể truy cập vào phương thức setSelectedElement.
Lấy window của bảng điều khiển tham chiếu
Để gọi postMessage() từ một bảng điều khiển công cụ cho nhà phát triển, bạn cần có một tham chiếu đến đối tượng window của đối tượng đó. Lấy cửa sổ iframe của bảng điều khiển từ trình xử lý sự kiện panel.onShown:
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Gửi thông báo từ tập lệnh được chèn đến trang Công cụ cho nhà phát triển
Mã được chèn trực tiếp vào trang mà không có tập lệnh nội dung, kể cả bằng cách nối thẻ <script> hoặc gọi inspectedWindow.eval(), không thể gửi thông báo đến trang Công cụ cho nhà phát triển bằng runtime.sendMessage(). Thay vào đó, bạn nên kết hợp tập lệnh được chèn với một tập lệnh nội dung có thể đóng vai trò là trung gian và sử dụng phương thức window.postMessage(). Ví dụ sau đây sử dụng tập lệnh nền ở phần trước:
// 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);
});
Bạn có thể tìm thấy các kỹ thuật truyền thông báo thay thế khác trên GitHub.
Phát hiện thời điểm Công cụ cho nhà phát triển mở và đóng
Để theo dõi xem cửa sổ Công cụ cho nhà phát triển có đang mở hay không, hãy thêm một trình nghe onConnect vào trình chạy dịch vụ và gọi connect() từ trang Công cụ cho nhà phát triển. Vì mỗi thẻ có thể mở cửa sổ Công cụ cho nhà phát triển riêng, nên bạn có thể nhận được nhiều sự kiện kết nối. Để theo dõi xem có cửa sổ Công cụ cho nhà phát triển nào đang mở hay không, hãy đếm các sự kiện kết nối và ngắt kết nối như minh hoạ trong ví dụ sau:
// 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.");
}
});
}
});
Trang Công cụ cho nhà phát triển sẽ tạo một kết nối như sau:
// 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);
Ví dụ về tiện ích Công cụ cho nhà phát triển
Các ví dụ trên trang này được lấy từ các trang sau:
- Tiện ích Polymer Devtools – Sử dụng nhiều trình trợ giúp chạy trong trang lưu trữ để truy vấn trạng thái DOM/JS nhằm gửi lại cho bảng điều khiển tuỳ chỉnh.
- Tiện ích React DevTools – Sử dụng một mô-đun con của trình kết xuất để sử dụng lại các thành phần giao diện người dùng của Công cụ cho nhà phát triển.
- Ember Inspector – Tiện ích dùng chung có các bộ chuyển đổi cho cả Chrome và Firefox.
- Coquette-inspect – Một tiện ích dựa trên React gọn gàng với một tác nhân gỡ lỗi được chèn vào trang lưu trữ.
- Tiện ích mẫu có nhiều tiện ích đáng cài đặt, dùng thử và tìm hiểu hơn.
Thông tin khác
Để biết thông tin về các API tiêu chuẩn mà tiện ích có thể sử dụng, hãy xem chrome.* API và API web.
Gửi ý kiến phản hồi cho chúng tôi! Ý kiến nhận xét và đề xuất của bạn sẽ giúp chúng tôi cải thiện các API này.
Ví dụ
Bạn có thể tìm thấy các ví dụ sử dụng API Công cụ cho nhà phát triển trong phần Mẫu.