Mở rộng Công cụ cho nhà phát triển

Các tiện ích DevTools thêm 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.

Sơ đồ cấu trúc cho thấy trang DevTools giao tiếp với cửa sổ được kiểm tra và worker dịch vụ. Trình chạy dịch vụ hiển thị đang giao tiếp với các tập lệnh nội dung và truy cập vào API tiện ích.
         Trang DevTools có quyền truy cập vào các API DevTools, ví dụ: tạo bảng điều khiển.
Cấu trúc tiện ích DevTools.

Các API tiện ích dành riêng cho DevTools bao gồm:

Trang Công cụ cho nhà phát triển

Khi cửa sổ DevTools mở ra, một tiện ích DevTools sẽ tạo một thực thể của trang DevTools. Thực thể này tồn tại miễn là cửa sổ đang mở. Trang này có quyền truy cập vào các API DevTools và API tiện ích, đồng thời có thể thực hiện những việc sau:

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 khả năng giao tiếp với worker dịch vụ bằng cách chuyển tin nhắn.

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",
  "devtools_page": "devtools.html",
  ...
}

Trường devtools_page phải trỏ đến một trang HTML. Vì trang DevTools phải nằm trên máy của phần mở rộng, nên bạn nên chỉ định trang đó bằng URL tương đối.

Các thành viên của API chrome.devtools chỉ dành cho các trang được tải trong cửa sổ DevTools 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.

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. 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, các ngăn thanh bên có thể trông giống như hình ảnh ví dụ sau:
Cửa sổ DevTools hiển thị bảng điều khiển Elements (Thành phần) và ngăn thanh bên Styles (Kiểu).
Cửa sổ DevTools hiển thị bảng điều khiển Elements (Thành phần) và ngăn thanh bên Styles (Kiểu).

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 sử 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 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.

Để tạo ngăn thanh bên cơ bản, hãy sử 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 thanh 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 đối tượng JSON đến setObject().
  • Biểu thức JavaScript: Truyền một biểu thức đến setExpression(). DevTools đánh giá biểu thức trong ngữ cảnh của trang được kiểm tra, sau đó hiển thị giá trị trả về.

Đối với cả setObject()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 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 DevTools giao tiếp với nhau.

Chèn tập lệnh nội dung

Để chèn 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ã 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 các API nhắn tin để giao tiếp với tập lệnh đó.

Đá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. 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 vào bảng điều khiển DevTools, cho phép truy cập vào các tính năng Console Utilities API (API tiện ích bảng điều khiển) của DevTools khi sử dụng eval(). Ví dụ: sử dụng hàm này để 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 ngữ cảnh với tập lệnh nội dung. Để sử dụng tuỳ chọn này, hãy sử dụng thông báo 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 ngữ cảnh tập lệnh ngữ cảnh tải, bạn cũng có thể sử dụng tuỳ chọn này để chèn các tập lệnh nội dung bổ sung.

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à API tiện ích bảng điều khiển. 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:

  1. 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ố.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. 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ọn useContentScriptContext: true.

    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 tham chiếu

Để gọi 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 đó. 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ừ các tập lệnh được chèn vào 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, bao gồm cả việc thêm thẻ <script> hoặc gọi inspectedWindow.eval(), không thể gửi thông báo đến trang DevTools bằng runtime.sendMessage(). Thay vào đó, bạn nên kết hợp tập lệnh đã 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 sử dụng tập lệnh trong nền từ 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 tin thay thế khác trên GitHub.

Phát hiện thời điểm DevTools mở và đóng

Để theo dõi xem cửa sổ DevTools có đang mở hay không, hãy thêm trình nghe onConnect vào worker dịch vụ và gọi connect() từ trang DevTools. Vì mỗi thẻ có thể mở một 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, 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 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 DevTools

Các ví dụ trên trang này được lấy từ các trang 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 trình kết xuất để 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ữ.
  • Tiện ích mẫu có nhiều tiện ích đáng giá hơn để cài đặt, dùng thử và tìm hiểu.

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.* APIAPI 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.