Descripción general de la arquitectura

Las extensiones son paquetes comprimidos de HTML, CSS, JavaScript, imágenes y otros archivos que se usan en la plataforma web, para personalizar la experiencia de navegación de Google Chrome. Las extensiones se compilan con tecnología web y pueden usar las mismas APIs que el navegador proporciona para la Web abierta.

Las extensiones tienen una amplia gama de posibilidades funcionales. Pueden modificar el contenido web que los usuarios ven y, además, interactuar con él, o extender y cambiar el comportamiento del navegador.

Considera las extensiones como la puerta de enlace para hacer del navegador Chrome el navegador más personalizado.

Archivos de extensión

Las extensiones varían según el tipo de archivo y la cantidad de directorios, pero todas deben tener un [manifiesto][docs-manifest]. Algunas extensiones básicas, pero útiles, pueden consistir solo en el manifiesto y el ícono de la barra de herramientas.

El archivo de manifiesto, llamado manifest.json, le brinda al navegador información sobre la extensión, como los archivos más importantes y las capacidades que podría usar.

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

Las extensiones deben tener un ícono en la barra de herramientas del navegador. Los íconos de la barra de herramientas permiten un acceso fácil y mantienen a los usuarios al tanto de qué extensiones están instaladas. La mayoría de los usuarios interactuarán con una extensión que usa una ventana emergente cuando hagan clic en el ícono.

Esta extensión Google Mail Checker utiliza una acción del navegador:

Captura de pantalla de la extensión Google Mail Checker

Esta extensión de Mappy usa una acción de página y una secuencia de comandos de contenido:

Captura de pantalla de la extensión Mappy

Cómo hacer referencia a los archivos

Se puede hacer referencia a los archivos de una extensión mediante una URL relativa, al igual que los archivos en una página HTML común.

<img src="images/my_image.png">

Además, se puede acceder a cada archivo con una URL absoluta.

chrome-extension://EXTENSION_ID/PATH_TO_FILE

En la URL absoluta, EXTENSION_ID es un identificador único que genera el sistema de extensiones para cada extensión. Los IDs de todas las extensiones cargadas se pueden ver en la URL chrome://extensions. PATH_TO_FILE es la ubicación del archivo en la carpeta superior de la extensión; coincide con la URL relativa.

Mientras se trabaja en una extensión sin empaquetar, el ID de la extensión puede cambiar. Específicamente, el ID de una extensión sin empaquetar cambiará si la extensión se carga desde un directorio diferente; el ID cambiará de nuevo cuando se empaquete la extensión. Si el código de una extensión se basa en una URL absoluta, puede usar el método chrome.runtime.getURL() para evitar codificar el ID durante el desarrollo.

Arquitectura

La arquitectura de una extensión dependerá de su funcionalidad, pero muchas extensiones sólidas incluirán varios componentes:

Secuencia de comandos en segundo plano

La secuencia de comandos en segundo plano es el controlador de eventos de la extensión. Contiene objetos de escucha para los eventos del navegador que son importantes para la extensión. Permanece inactivo hasta que se activa un evento y, luego, realiza la lógica indicada. Una secuencia de comandos eficaz en segundo plano solo se carga cuando es necesaria y se descarga cuando queda inactiva.

Elementos de la IU

La interfaz de usuario de una extensión debe ser significativa y mínima. La IU debe personalizar o mejorar la experiencia de navegación sin distraerse de ella. La mayoría de las extensiones tienen una acción de navegador o una acción de página, pero pueden contener otras formas de IU, como menús contextuales, el uso del cuadro multifunción o la creación de una combinación de teclas.

Las páginas de extensiones de la IU, como una ventana emergente, pueden contener páginas HTML comunes con lógica de JavaScript. Las extensiones también pueden llamar a tabs.create o window.open() para mostrar archivos HTML adicionales presentes en la extensión.

Una extensión que usa una acción de página y una ventana emergente puede usar la API de contenido declarativo a fin de establecer reglas en la secuencia de comandos en segundo plano para cuando la ventana emergente esté disponible para los usuarios. Cuando se cumplen las condiciones, la secuencia de comandos en segundo plano se comunica con la ventana emergente para que los usuarios puedan hacer clic en el ícono.

Una ventana del navegador con una acción de la página en la que se muestra una ventana emergente

Secuencias de comandos de contenido

Las extensiones que leen o escriben en páginas web usan una secuencia de comandos de contenido. La secuencia de comandos del contenido incluye JavaScript que se ejecuta en los contextos de una página que se cargó en el navegador. Las secuencias de comandos de contenido leen y modifican el DOM de las páginas web que visita el navegador.

Una ventana del navegador con una acción de la página y una secuencia de comandos de contenido

Las secuencias de comandos de contenido pueden comunicarse con su extensión superior mediante el intercambio de mensajes y el almacenamiento de valores con la API de storage.

Muestra una ruta de comunicación entre la secuencia de comandos del contenido y la extensión superior

Página de opciones

Así como las extensiones permiten a los usuarios personalizar el navegador Chrome, la página de opciones permite personalizar la extensión. Las opciones se pueden usar para habilitar funciones y permitir que los usuarios elijan qué funciones son relevantes para sus necesidades.

Uso de las APIs de Chrome

Además de tener acceso a las mismas APIs que las páginas web, las extensiones también pueden usar APIs específicas de extensiones que crean una integración estrecha con el navegador. Las extensiones y las páginas web pueden acceder al método window.open() estándar para abrir una URL, pero las extensiones pueden especificar en qué ventana se debe mostrar esa URL mediante el método tabs.create de la API de Chrome.

Métodos asíncronos frente a síncronos

La mayoría de los métodos de la API de Chrome son asíncronos, es decir, se muestran de inmediato sin esperar a que finalice la operación. Si una extensión necesita conocer el resultado de una operación asíncrona, puede pasar una función de devolución de llamada al método. La devolución de llamada se ejecuta más tarde, posiblemente mucho más tarde, después de que se muestra el método.

Si la extensión necesita navegar por la pestaña seleccionada actualmente del usuario a una URL nueva, deberá obtener el ID de la pestaña actual y, luego, actualizar la dirección de esa pestaña a la nueva URL.

Si el método tabs.query fuera síncrono, es posible que se vea similar a lo que se muestra a continuación.

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

Este enfoque fallará porque query() es asíncrono. Se muestra sin esperar a que se complete el trabajo y no muestra ningún valor. Un método es asíncrono cuando el parámetro de devolución de llamada está disponible en su firma.

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

Para consultar una pestaña y actualizar su URL correctamente, la extensión debe usar el parámetro de devolución de llamada.

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

En el código anterior, las líneas se ejecutan en el siguiente orden: 1, 4, 2. Se llama a la función de devolución de llamada especificada en query() y, luego, se ejecuta la línea 2, pero solo después de que esté disponible la información sobre la pestaña seleccionada. Esto sucede en algún momento después de que se devuelve query(). Aunque update() es asíncrono, el código no usa un parámetro de devolución de llamada, ya que la extensión no hace nada con los resultados de la actualización.

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

Este método muestra la URL de forma síncrona como un string y no realiza ningún otro trabajo asíncrono.

Más detalles

Si deseas más información, explora los documentos de referencia de la API de Chrome y mira el siguiente video.

Comunicación entre páginas

A menudo, los diferentes componentes de una extensión necesitan comunicarse entre sí. Las diferentes páginas HTML pueden encontrarse entre sí mediante los métodos chrome.extension, como getViews() y getBackgroundPage(). Una vez que una página tenga referencia a otras páginas de extensión, la primera puede invocar funciones en las otras páginas y manipular sus DOM. Además, todos los componentes de la extensión pueden acceder a los valores almacenados con la API de storage y comunicarse a través de la transferencia de mensajes.

Almacenamiento de datos y modo Incógnito

Las extensiones pueden guardar datos con la API de storage, la API de Web Storage de HTML5 o mediante solicitudes del servidor que ahorran datos. Cuando la extensión necesite guardar algo, primero considera si proviene de una ventana de incógnito. De forma predeterminada, las extensiones no se ejecutan en ventanas de incógnito.

El modo Incógnito promete que la ventana no dejará rastros. Cuando se trata de datos de ventanas de incógnito, las extensiones deben cumplir esta promesa. Si una extensión suele guardar el historial de navegación, no guardes el historial de las ventanas de incógnito. Sin embargo, las extensiones pueden almacenar las preferencias de configuración desde cualquier ventana, ya sea en modo Incógnito o no.

Para detectar si una ventana está en modo Incógnito, verifica la propiedad incognito del objeto tabs.Tab o windows.Window relevante.

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

Da el siguiente paso

Después de leer la descripción general y completar el instructivo de introducción, los desarrolladores deberían estar listos para comenzar a escribir sus propias extensiones. Sumérgete en el mundo de Chrome personalizado con los siguientes recursos.