Descripción general
Una extensión de DevTools agrega funcionalidad a las Herramientas para desarrolladores de Chrome. Puede agregar nuevos paneles y barras laterales de la IU, interactuar con la página inspeccionada, obtener información sobre las solicitudes de red y mucho más. Consulta las extensiones destacadas de DevTools. Las extensiones de DevTools tienen acceso a un conjunto adicional de APIs de extensiones específicas de DevTools:
Una extensión de DevTools se estructura como cualquier otra extensión: puede tener una página en segundo plano, secuencias de comandos de contenido y otros elementos. Además, cada extensión de DevTools tiene una página de DevTools, que tiene acceso a las APIs de DevTools.

La página de Herramientas para desarrolladores
Se crea una instancia de la página de DevTools de la extensión cada vez que se abre una ventana de DevTools. La página de DevTools existe durante la vida útil de la ventana de DevTools. La página de Herramientas para desarrolladores tiene acceso a las APIs de Herramientas para desarrolladores y a un conjunto limitado de APIs de extensiones. Específicamente, la página de Herramientas para desarrolladores puede hacer lo siguiente:
- Crea paneles e interactúa con ellos a través de las APIs de
devtools.panels. - Obtener información sobre la ventana inspeccionada y evaluar el código en ella con las APIs de
devtools.inspectedWindow - Obtén información sobre las solicitudes de red con las APIs de
devtools.network.
La página de Herramientas para desarrolladores no puede usar la mayoría de las APIs de extensiones directamente. Tiene acceso al mismo subconjunto de las APIs de extension y runtime al que tiene acceso una secuencia de comandos de contenido. Al igual que una secuencia de comandos de contenido, una página de Herramientas para desarrolladores puede comunicarse con la página en segundo plano a través del paso de mensajes. Para ver un ejemplo, consulta Cómo insertar una secuencia de comandos de contenido.
Cómo crear una extensión de DevTools
Para crear una página de DevTools para tu extensión, agrega el campo devtools_page en el manifiesto de la extensión:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
Se crea una instancia del objeto devtools_page especificado en el manifiesto de tu extensión para cada ventana de Herramientas para desarrolladores que se abre. La página puede agregar otras páginas de extensión como paneles y barras laterales a la ventana de Herramientas para desarrolladores con la API de devtools.panels.
Los módulos de la API de chrome.devtools.* solo están disponibles para las páginas cargadas en la ventana de Herramientas para desarrolladores. Las secuencias de comandos de contenido y otras páginas de extensión no tienen estas APIs. Por lo tanto, las APIs solo están disponibles durante la vida útil de la ventana de Herramientas para desarrolladores.
También hay algunas APIs de Herramientas para desarrolladores que aún son experimentales. Consulta chrome.experimental.* APIs para obtener la lista de APIs experimentales y los lineamientos para usarlas.
Elementos de la IU de Herramientas para desarrolladores: paneles y paneles laterales
Además de los elementos de IU habituales de las extensiones, como las acciones del navegador, los menús contextuales y las ventanas emergentes, una extensión de Herramientas para desarrolladores puede agregar elementos de IU a la ventana de Herramientas para desarrolladores:
- Un panel es una pestaña de nivel superior, como los paneles Elements, Sources y Network.
- Un panel lateral presenta una IU complementaria relacionada con un panel. Los paneles Styles, Computed Styles y Event Listeners del panel Elements son ejemplos de paneles laterales. (Ten en cuenta que la apariencia de los paneles de la barra lateral puede no coincidir con la imagen, según la versión de Chrome que uses y dónde esté anclada la ventana de Herramientas para desarrolladores).

Cada panel es su propio archivo HTML, que puede incluir otros recursos (JavaScript, CSS, imágenes, etc.). La creación de un panel básico se ve de la siguiente manera:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
El código JavaScript que se ejecuta en un panel o en un panel lateral tiene acceso a las mismas APIs que la página de Herramientas para desarrolladores.
La creación de un panel lateral básico para el panel Elementos se ve de la siguiente manera:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
Hay varias formas de mostrar contenido en un panel lateral:
- Contenido HTML. Llama a
setPagepara especificar una página HTML que se mostrará en el panel. - Son datos JSON. Pasa un objeto JSON a
setObject. - Es una expresión de JavaScript. Pasa una expresión a
setExpression. Herramientas para desarrolladores evalúa la expresión en el contexto de la página inspeccionada y muestra el valor de devolución.
Tanto para setObject como para setExpression, el panel muestra el valor tal como aparecería en la consola de Herramientas para desarrolladores. Sin embargo, setExpression te permite mostrar elementos del DOM y objetos JavaScript arbitrarios, mientras que setObject solo admite objetos JSON.
Comunicación entre componentes de la extensión
En las siguientes secciones, se describen algunos casos típicos de comunicación entre los diferentes componentes de una extensión de Herramientas para desarrolladores.
Cómo insertar una secuencia de comandos de contenido
La página de Herramientas para desarrolladores no puede llamar a tabs.executeScript directamente. Para insertar una secuencia de comandos de contenido desde la página de Herramientas para desarrolladores, debes recuperar el ID de la pestaña de la ventana inspeccionada con la propiedad inspectedWindow.tabId y enviar un mensaje a la página en segundo plano. Desde la página en segundo plano, llama a tabs.executeScript para insertar el script.
En los siguientes fragmentos de código, se muestra cómo insertar una secuencia de comandos de contenido con 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"
});
Código de la página en segundo plano:
// 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);
});
});
Cómo evaluar JavaScript en la ventana inspeccionada
Puedes usar el método inspectedWindow.eval para ejecutar código JavaScript en el contexto de la página inspeccionada. Puedes invocar el método eval desde una página, un panel o un panel lateral de Herramientas para desarrolladores.
De forma predeterminada, la expresión se evalúa en el contexto del marco principal de la página. Es posible que ya conozcas las funciones de la API de línea de comandos de Herramientas para desarrolladores, como la inspección de elementos (inspect(elem)), la interrupción en funciones (debug(fn)), la copia al portapapeles (copy()) y muchas más.
inspectedWindow.eval() usa el mismo contexto y las mismas opciones de ejecución de secuencias de comandos que el código escrito en la consola de Herramientas para desarrolladores, lo que permite acceder a estas APIs dentro de la evaluación. Por ejemplo, SOAK lo usa para inspeccionar un elemento:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
Como alternativa, usa la opción useContentScriptContext: true para inspectedWindow.eval() y evalúa la expresión en el mismo contexto que las secuencias de comandos de contenido. Llamar a eval con useContentScriptContext: true no crea un contexto de secuencia de comandos de contenido, por lo que debes cargar una secuencia de comandos de contexto antes de llamar a eval, ya sea llamando a executeScript o especificando una secuencia de comandos de contenido en el archivo manifest.json.
Una vez que existe el contexto de la secuencia de comandos de contexto, puedes usar esta opción para insertar secuencias de comandos de contenido adicionales.
El método eval es potente cuando se usa en el contexto adecuado y peligroso cuando se usa de forma inapropiada. Usa el método tabs.executeScript si no necesitas acceder al contexto de JavaScript de la página inspeccionada. Para obtener advertencias detalladas y una comparación de los dos métodos, consulta inspectedWindow.
Cómo pasar el elemento seleccionado a un script de contenido
La secuencia de comandos de contenido no tiene acceso directo al elemento seleccionado actual. Sin embargo, cualquier código que ejecutes con inspectedWindow.eval tiene acceso a la consola de Herramientas para desarrolladores y a las APIs de línea de comandos.
Por ejemplo, en el código evaluado, puedes usar $0 para acceder al elemento seleccionado.
Para pasar el elemento seleccionado a una secuencia de comandos de contenido, haz lo siguiente:
- Crea un método en la secuencia de comandos de contenido que tome el elemento seleccionado como argumento.
- Llama al método desde la página de Herramientas para desarrolladores con
inspectedWindow.evaly la opciónuseContentScriptContext: true.
El código de tu secuencia de comandos de contenido podría verse de la siguiente manera:
function setSelectedElement(el) {
// do something with the selected element
}
Invoca el método desde la página de Herramientas para desarrolladores de la siguiente manera:
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
La opción useContentScriptContext: true especifica que la expresión se debe evaluar en el mismo contexto que las secuencias de comandos de contenido, por lo que puede acceder al método setSelectedElement.
Cómo obtener el window de un panel de referencia
Para postMessage desde un panel de Herramientas para desarrolladores, necesitarás una referencia a su objeto window.
Obtén la ventana iframe de un panel desde el controlador de eventos panel.onShown:
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Envío de mensajes desde secuencias de comandos de contenido a la página de Herramientas para desarrolladores
La mensajería entre la página de DevTools y las secuencias de comandos de contenido es indirecta, a través de la página en segundo plano.
Cuando se envía un mensaje a una secuencia de comandos de contenido, la página en segundo plano puede usar el método tabs.sendMessage, que dirige un mensaje a las secuencias de comandos de contenido en una pestaña específica, como se muestra en Cómo insertar una secuencia de comandos de contenido.
Cuando se envía un mensaje desde un script de contenido, no hay un método listo para usar para entregar un mensaje a la instancia correcta de la página de Herramientas para desarrolladores asociada con la pestaña actual. Como solución alternativa, puedes hacer que la página de Herramientas para desarrolladores establezca una conexión duradera con la página en segundo plano y que esta mantenga un mapa de los IDs de las pestañas y las conexiones para poder enrutar cada mensaje a la conexión correcta.
// 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;
});
La página de Herramientas para desarrolladores (o el panel o el panel lateral) establece la conexión de la siguiente manera:
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
Envío de mensajes desde los secuencias de comandos insertados a la página de Herramientas para desarrolladores
Si bien la solución anterior funciona para las secuencias de comandos de contenido, el código que se inyecta directamente en la página (p.ej., agregando una etiqueta <script> o a través de inspectedWindow.eval) requiere una estrategia diferente. En este contexto, runtime.sendMessage no pasará mensajes al script en segundo plano como se espera.
Como solución alternativa, puedes combinar tu secuencia de comandos insertada con una secuencia de comandos de contenido que actúe como intermediaria. Para pasar mensajes a la secuencia de comandos de contenido, puedes usar la API de window.postMessage. Este es un ejemplo, suponiendo que el script de segundo plano de la sección anterior:
// 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);
});
Ahora, tu mensaje fluirá desde la secuencia de comandos insertada hasta la secuencia de comandos de contenido, luego a la secuencia de comandos en segundo plano y, finalmente, a la página de Herramientas para desarrolladores.
También puedes considerar dos técnicas alternativas de transmisión de mensajes aquí.
Cómo detectar cuándo se abren y cierran las Herramientas para desarrolladores
Si tu extensión necesita hacer un seguimiento para saber si la ventana de Herramientas para desarrolladores está abierta, puedes agregar un objeto de escucha onConnect a la página en segundo plano y llamar a connect desde la página de Herramientas para desarrolladores. Dado que cada pestaña puede tener su propia ventana de Herramientas para desarrolladores abierta, es posible que recibas varios eventos de conexión. Para hacer un seguimiento de si alguna ventana de Herramientas para desarrolladores está abierta, debes contar los eventos de conexión y desconexión, como se muestra a continuación:
// 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.");
}
});
}
});
La página de Herramientas para desarrolladores crea una conexión como esta:
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
Ejemplos de extensiones de DevTools
Explora el código fuente de estos ejemplos de extensiones de DevTools:
- Extensión de Polymer Devtools: Usa muchos asistentes que se ejecutan en la página host para consultar el estado del DOM/JS y enviarlo de vuelta al panel personalizado.
- Extensión de React DevTools: Usa un submódulo de Blink para reutilizar los componentes de la IU de DevTools.
- Ember Inspector: Es el núcleo de la extensión compartida con adaptadores para Chrome y Firefox.
- Coquette-inspect: Es una extensión limpia basada en React con un agente de depuración insertado en la página host.
- Nuestra Galería de extensiones de DevTools y nuestras Extensiones de muestra tienen más apps valiosas para instalar, probar y aprender.
Más información
Para obtener información sobre las APIs estándar que pueden usar las extensiones, consulta chrome.* APIs y APIs web.
Envíanos tus comentarios Tus comentarios y sugerencias nos ayudan a mejorar las APIs.
Ejemplos
Puedes encontrar ejemplos que usan las APIs de DevTools en Samples.