Tổng quan
Tiện ích DevTools sẽ thêm chức năng vào Chrome DevTools. Trình bổ trợ này có thể thêm các bảng điều khiển giao diện người dùng và bảng điều khiển bên mới, tương tác với trang được kiểm tra, nhận thông tin về các yêu cầu mạng và nhiều tính năng khác. Xem các tiện ích DevTools nổi bật. Các tiện ích DevTools có quyền truy cập vào một nhóm API tiện ích bổ sung dành riêng cho DevTools:
Tiện ích DevTools có cấu trúc giống như mọi tiện ích khác: có thể có trang nền, tập lệnh nội dung và các mục khác. Ngoài ra, mỗi tiện ích DevTools đều có một trang DevTools có quyền truy cập vào các API DevTools.
Trang Công cụ cho nhà phát triển
Một thực thể của trang DevTools của tiện ích sẽ được tạo mỗi khi cửa sổ DevTools mở ra. Trang DevTools tồn tại trong toàn bộ thời gian hoạt động của cửa sổ DevTools. Trang DevTools có quyền truy cập vào các API DevTools và một số API tiện ích bị hạn chế. Cụ thể, trang Công cụ cho nhà phát triển có thể:
- Tạo và tương tác với các bảng điều khiển bằng API
devtools.panels
. - 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ác API
devtools.inspectedWindow
. - Nhận thông tin về các yêu cầu mạng bằng API
devtools.network
.
Trang Công cụ dành cho nhà phát triển không thể sử dụng trực tiếp hầu hết các API tiện ích. Tập lệnh này có quyền truy cập vào cùng một tập hợp con của các API extension
và runtime
mà tập lệnh nội dung có quyền truy cập. Giống như tập lệnh nội dung, trang DevTools có thể giao tiếp với trang ở chế độ nền bằng cách sử dụng tính năng Chuyển tin nhắn. Để biết ví dụ, hãy xem phần Chèn tập lệnh nội dung.
Tạo phần mở rộng DevTools
Để tạo trang DevTools cho tiện ích, hãy thêm trường devtools_page
vào tệp kê khai của tiện ích:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
Một thực thể của devtools_page
được chỉ định trong tệp kê khai của tiện ích sẽ được tạo cho mỗi cửa sổ DevTools được mở. Trang này có thể thêm các trang tiện ích khác dưới dạng bảng điều khiển và thanh bên vào cửa sổ DevTools bằng API devtools.panels
.
Các mô-đun API chrome.devtools.*
chỉ dành cho các trang được tải trong cửa sổ DevTools. Tập lệnh nội dung và các trang tiện ích khác không có các API này. Do đó, các API chỉ có sẵn trong suốt thời gian tồn tại của cửa sổ DevTools.
Ngoài ra, một số API DevTools vẫn đang trong giai đoạn thử nghiệm. Tham khảo chrome.experimental.* API để xem danh sách API thử nghiệm và nguyên tắc sử dụng các API đó.
Các phần tử trên giao diện người dùng của DevTools: bảng điều khiển và ngăn thanh bên
Ngoài các thành phần trên giao diện người dùng của 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 thành phần trên 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 thanh bên hiển thị 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 Kiểu, Kiểu đã tính toán và Trình nghe sự kiện trên bảng điều khiển Phần tử là ví dụ về các ngăn thanh bên. (Lưu ý rằng giao diện của các ngăn thanh bên có thể không khớp với hình ảnh, tuỳ thuộc vào phiên bản Chrome bạn đang sử dụng và vị trí cửa sổ DevTools được neo.)
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.). Cách tạo một bảng điều khiển cơ bản như sau:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript được thực thi trong bảng điều khiển hoặc ngăn thanh bên có quyền truy cập vào các API giống như trang DevTools.
Cách tạo ngăn thanh bên cơ bản cho bảng điều khiển Elements (Thành phần) như 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 thanh bên:
- Nội dung HTML. Gọi
setPage
để chỉ định một trang HTML 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 vào
setExpression
. Công cụ cho nhà phát triển sẽ đánh giá biểu thức trong ngữ cảnh của trang được kiểm tra và 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ư sẽ xuất hiện trong bảng điều khiển DevTools. Tuy nhiên, setExpression
cho phép bạn hiển thị các phần tử DOM và đố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ố trường hợp thông thường để giao tiếp giữa các thành phần khác nhau của một tiện ích DevTools.
Chèn tập lệnh nội dung
Trang Công cụ cho nhà phát triển không thể gọi trực tiếp tabs.executeScript
. Để chèn tập lệnh nội dung từ trang DevTools, bạn phải truy xuất mã nhận dạng của thẻ cửa sổ đã kiểm tra bằng cách sử dụng thuộc tính inspectedWindow.tabId
và gửi thông báo đến trang nền. Từ trang nền, hãy gọi tabs.executeScript
để chèn tập lệnh.
Các đoạn mã sau đây cho biết cách chèn tập lệnh nội dung bằng executeScript
.
// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
backgroundPageConnection.onMessage.addListener(function (message) {
// Handle responses from the background page, if any
});
// Relay the tab ID to the background page
chrome.runtime.sendMessage({
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content_script.js"
});
Mã cho trang nền:
// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
// assign the listener function to a variable so we can remove it later
var devToolsListener = function(message, sender, sendResponse) {
// Inject a content script into the identified tab
chrome.tabs.executeScript(message.tabId,
{ file: message.scriptToInject });
}
// add the listener
devToolsConnection.onMessage.addListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function() {
devToolsConnection.onMessage.removeListener(devToolsListener);
});
});
Đánh giá JavaScript trong cửa sổ đã kiểm tra
Bạn có thể sử dụng phương thức inspectedWindow.eval
để thực thi mã JavaScript trong ngữ 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 thanh bên của DevTools.
Theo mặc định, biểu thức được đánh giá trong ngữ cảnh của khung chính của trang. Giờ đây, bạn có thể quen thuộc với các tính năng API dòng lệnh của DevTools như kiểm tra phần tử (inspect(elem)
), ngắt trên các hàm (debug(fn)
), sao chép vào bảng nhớ tạm (copy()
) và nhiều tính năng khác.
inspectedWindow.eval()
sử dụng cùng một ngữ cảnh thực thi tập lệnh và các tuỳ chọn như mã được nhập tại bảng điều khiển DevTools, cho phép truy cập vào các API này trong eval. Ví dụ: SOAK sử dụng hàm này để kiểm tra một phần tử:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
Ngoài ra, hãy sử dụng tuỳ chọn useContentScriptContext: true
cho inspectedWindow.eval()
để đánh giá biểu thức trong cùng ngữ cảnh với tập lệnh nội dung. Việc gọi eval
bằng useContentScriptContext: true
không create ngữ cảnh tập lệnh nội dung, vì vậy, bạn phải tải tập lệnh ngữ cảnh trước khi gọi eval
, bằng cách gọi executeScript
hoặc chỉ định tập lệnh nội dung trong tệp manifest.json
.
Khi tập lệnh ngữ cảnh tồn tại, bạn có thể sử dụng tuỳ chọn này để chèn các tập lệnh nội dung bổ sung.
Phương thức eval
rất mạnh mẽ khi được sử dụng đúng ngữ cảnh và nguy hiểm khi được sử dụng không phù hợp. Sử dụng phương thức tabs.executeScript
nếu bạn không cần quyền truy cập vào ngữ cảnh JavaScript của trang được kiểm tra. Để biết các lưu ý chi tiết và thông tin so sánh giữa hai phương thức này, hãy xem inspectedWindow
.
Truyền phần tử đã chọn đến 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ử đã chọn hiện tại. 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à các API dòng lệnh.
Ví dụ: trong mã đã đá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 tập lệnh nội dung:
- Tạo một phương thức trong tập lệnh nội dung, phương thức này sẽ lấy phần tử đã chọn làm đối số.
- Gọi phương thức từ trang Công cụ cho nhà phát triển bằng
inspectedWindow.eval
với tuỳ chọnuseContentScriptContext: true
.
Mã trong tập lệnh nội dung của bạn có thể có dạng như sau:
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 như sau:
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
Tuỳ 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 để 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
Để postMessage
từ bảng điều khiển công cụ phát triển, bạn cần tham chiếu đến đối tượng window
của bảng điều khiển đó.
Nhận cửa sổ iframe của bảng điều khiển từ trình xử lý sự kiện panel.onShown
:
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Thông báo từ tập lệnh nội dung đến trang Công cụ cho nhà phát triển
Việc gửi thông báo giữa trang Công cụ cho nhà phát triển và tập lệnh nội dung là gián tiếp, thông qua trang nền.
Khi gửi thông báo cho tập lệnh nội dung, trang ở chế độ nền có thể sử dụng phương thức tabs.sendMessage
. Phương thức này sẽ chuyển hướng thông báo đến các tập lệnh nội dung trong một thẻ cụ thể, như trong phần Chèn tập lệnh nội dung.
Khi gửi thông báo từ tập lệnh nội dung, không có phương thức tạo sẵn nào để phân phối thông báo đến thực thể trang DevTools chính xác được liên kết với thẻ hiện tại. Để khắc phục, bạn có thể yêu cầu trang DevTools thiết lập một kết nối lâu dài với trang ở chế độ nền và yêu cầu trang ở chế độ nền lưu giữ bản đồ mã nhận dạng thẻ đến các kết nối để có thể định tuyến từng thông báo đến đúng kết nối.
// background.js
var connections = {};
chrome.runtime.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
// The original connection event doesn't include the tab ID of the
// DevTools page, so we need to send it explicitly.
if (message.name == "init") {
connections[message.tabId] = port;
return;
}
// other message handling
}
// Listen to messages sent from the DevTools page
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
var tabs = Object.keys(connections);
for (var i=0, len=tabs.length; i < len; i++) {
if (connections[tabs[i]] == port) {
delete connections[tabs[i]]
break;
}
}
});
});
// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// Messages from content scripts should have sender.tab set
if (sender.tab) {
var tabId = sender.tab.id;
if (tabId in connections) {
connections[tabId].postMessage(request);
} else {
console.log("Tab not found in connection list.");
}
} else {
console.log("sender.tab not defined.");
}
return true;
});
Trang DevTools (hoặc bảng điều khiển hoặc ngăn thanh bên) thiết lập kết nối như sau:
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
Thông báo từ tập lệnh được chèn vào trang Công cụ cho nhà phát triển
Mặc dù giải pháp trên hoạt động cho các tập lệnh nội dung, nhưng mã được chèn trực tiếp vào trang (ví dụ: thông qua việc thêm thẻ <script>
hoặc thông qua inspectedWindow.eval
) yêu cầu một chiến lược khác. Trong ngữ cảnh này, runtime.sendMessage
sẽ không truyền thông báo đến tập lệnh trong nền như dự kiến.
Để khắc phục, bạn có thể kết hợp tập lệnh đã chèn với tập lệnh nội dung đóng vai trò là trình trung gian. Để truyền thông báo đến tập lệnh nội dung, bạn có thể sử dụng API window.postMessage
. Dưới đây là ví dụ, giả sử tập lệnh trong 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
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
Giờ đây, thông báo của bạn sẽ chuyển từ tập lệnh được chèn, đến tập lệnh nội dung, đến tập lệnh trong nền và cuối cùng là đến trang DevTools.
Bạn cũng có thể xem xét hai kỹ thuật truyền tin nhắn thay thế tại đây.
Phát hiện thời điểm Công cụ cho nhà phát triển mở và đóng
Nếu tiện ích của bạn cần theo dõi xem cửa sổ DevTools có đang mở hay không, bạn có thể thêm trình nghe onConnect vào trang nền và gọi connect từ trang DevTools. Vì mỗi thẻ có thể mở cửa sổ DevTools 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ổ DevTools nào đang mở hay không, bạn cần đếm các sự kiện kết nối và ngắt kết nối như minh hoạ bên dưới:
// 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 tạo một kết nối như sau:
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
Ví dụ về tiện ích DevTools
Duyệt qua nguồn của các ví dụ về tiện ích DevTools sau:
- Tiện ích công cụ phát triển Polymer – 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 Blink để sử dụng lại các thành phần giao diện người dùng DevTools.
- Ember Inspector – Hạt nhân tiện ích dùng chung với bộ chuyển đổi cho cả Chrome và Firefox.
- Coquette-inspect – Một tiện ích dựa trên React sạch với một tác nhân gỡ lỗi được chèn vào trang lưu trữ.
- Thư viện tiện ích DevTools và Tiện ích mẫu của chúng tôi có nhiều ứng dụng đáng giá hơn để cài đặt, dùng thử và học hỏi.
Thông tin khác
Để biết thông tin về các API 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 giúp chúng tôi cải thiện các API.
Ví dụ
Bạn có thể tìm thấy các ví dụ sử dụng API DevTools trong phần Mẫu.