Workbox

Mantener la lógica de almacenamiento y el service worker y la caché puede ser un desafío a medida que crece tu AWP. Workbox es un conjunto de bibliotecas de código abierto que te ayudará con eso. Workbox encapsula las APIs de bajo nivel, como la API de Service Worker y Cache Storage, y expone interfaces más fáciles de usar para el desarrollador.

Algunas tareas con las que puede ayudar son hacer coincidir estrategias de almacenamiento en caché con rutas de acceso (o patrones de enrutamiento), trabajar con transmisiones y usar funciones como la sincronización en segundo plano con los resguardos adecuados.

Workbox puede ayudarte a administrar tus necesidades de entrega y almacenamiento en caché de recursos. También es la biblioteca más usada para los service workers; se usa en el 54% de los sitios móviles y se usa en muchas herramientas de compilación y CLI, incluidas la CLI de Angular, Create-React-App y la CLI de Vue. También existen complementos para la mayoría de las demás bibliotecas y frameworks, como Next.js.

El 54%

Los sitios móviles con service worker usan la biblioteca de Workbox

Módulos de la caja de trabajo

Workbox incluye varias bibliotecas, llamadas módulos internamente, cada una enfocada en un aspecto diferente de la administración de los recursos y el comportamiento de los service worker.

Los módulos de caja de trabajo funcionan en diferentes contextos, como los siguientes:

  • Dentro del contexto de un service worker: Se importan los módulos que necesitas y se usan desde el archivo del service worker, por ejemplo, para administrar el almacenamiento en caché y entregar archivos con distintas estrategias.
  • Dentro del contexto principal de window: Cómo ayudar a registrar un service worker y comunicarse con él
  • Como parte de un sistema de compilación: Por ejemplo, webpack, por ejemplo, para crear un manifiesto de tus recursos o incluso generar todo tu service worker.

Estos son algunos módulos populares:

  • workbox-routing: Cuando el service worker intercepta solicitudes, este módulo enruta esas solicitudes a diferentes funciones que proporcionan respuestas; se trata de una implementación del controlador de eventos fetch, como se menciona en el Capítulo Entrega.
  • estrategias del cuadro de trabajo: Es un conjunto de estrategias de almacenamiento en caché en el entorno de ejecución que controlan la respuesta a una solicitud, como la caché primero y la inactiva durante la revalidación. Se trata de una implementación de las diferentes estrategias mencionadas en el capítulo Entrega.
  • workbox-precaching: Es una implementación del almacenamiento en caché de archivos en el controlador de eventos install del service worker (también conocido como almacenamiento previo en caché), como se menciona en el Capítulo sobre almacenamiento en caché. Con este módulo, puedes almacenar previamente en caché un conjunto de archivos y administrar eficientemente las actualizaciones de esos elementos. Abordaremos la actualización de recursos en el capítulo Actualización.
  • workbox-expiration: Es un complemento que se usa con las estrategias de almacenamiento en caché para quitar solicitudes almacenadas en caché según la cantidad de elementos almacenados en caché o la antigüedad de las solicitudes en caché. Te ayuda a administrar las cachés y establece límites de tiempo y cantidad de elementos en cada caché.
  • workbox-window: Es un conjunto de módulos diseñados para ejecutarse en el contexto de la ventana, es decir, dentro de tus páginas web de AWP. Puedes simplificar el proceso de registro y actualizaciones de service worker, y facilitar la comunicación entre el código que se ejecuta en el contexto de service worker y el contexto de ventana.

Usa Workbox

Workbox ofrece diferentes maneras de integrar la AWP. Puedes elegir cuál se adapta mejor a la arquitectura de tu app:

  • CLI de Workbox: Es una utilidad de línea de comandos que genera un service worker completo, inserta un manifiesto de precaché o copia los archivos de Workbox necesarios.
  • Compilación de la unidad de trabajo: Es un módulo de npm que genera un service worker completo, inserta un manifiesto de precaché y copia los archivos de Workbox. Está pensado para integrarse con tu propio proceso de compilación.
  • workbox-sw: Es una forma de cargar paquetes de service worker de Workbox desde una CDN que no usa un proceso de compilación.

La CLI de Workbox proporciona un asistente que te guiará para crear el service worker. Para ejecutar el asistente, escribe lo siguiente en una línea de comandos:

npx workbox-cli wizard

La CLI de Workbox en acción en una terminal

Almacenamiento en caché y entrega con Workbox

Un uso común de Workbox es usar los módulos de enrutamiento y estrategias juntos para almacenar en caché y entregar archivos.

El módulo Estrategias del cuadro de trabajo proporciona, de forma predeterminada, las estrategias de almacenamiento en caché que se analizan en los capítulos Recursos y datos y Entrega.

El módulo de workbox-routing ayuda a ordenar las solicitudes entrantes a tu service worker y a hacer coincidir las estrategias o funciones de almacenamiento en caché con el fin de obtener respuestas para esas solicitudes.

Después de la coincidencia de rutas a estrategias, Workbox también ofrece la capacidad de filtrar qué respuestas se agregarán a la caché con el complemento workbox-cacheable-response. Con este complemento, por ejemplo, puedes almacenar en caché solo las respuestas que se mostraron sin errores.

En la siguiente muestra de código, se usa una estrategia centrada en la caché (a través del módulo CacheFirst) para almacenar en caché y publicar navegaciones de páginas.

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';

const pageStrategy = new CacheFirst({
  // Put all cached files in a cache named 'pages'
  cacheName: 'pages',
  plugins: [
    // Only requests that return with a 200 status are cached
    new CacheableResponsePlugin({
      statuses: [200],
    }),
  ],
});

El complemento te permite aprovechar el ciclo de vida de resolución de solicitudes y almacenamiento en caché de Workbox. Aquí, el CacheableResponsePlugin solo se usa para almacenar en caché las solicitudes que den como resultado un estado 200, lo que evita que las solicitudes incorrectas se guarden en la caché.

Una vez creada la estrategia, es hora de registrar una ruta para usarla. En el siguiente ejemplo, se llama a registerRoute() y se pasa un objeto Request a su devolución de llamada. Si request.mode es "navigate", usa la estrategia CacheFirst (aquí llamada pageStrategy) que se definió en el ejemplo de código anterior.

// Cache page navigations (HTML) with a Cache First strategy
registerRoute( ({ request }) => request.mode === 'navigate',
  pageStrategy );

Lee la documentación de Workbox para ver más ejemplos y prácticas recomendadas.

Resguardo sin conexión

El módulo de workbox-routing también tiene un setCatchHandler() exportado, que proporciona control en caso de que una ruta arroja un error. Puedes usar esta opción para configurar un resguardo sin conexión y notificar a los usuarios que la ruta solicitada no está disponible actualmente.

Aquí, una combinación de Workbox y la API de Cache Storage proporciona un resguardo sin conexión a través de una estrategia de solo caché. Primero, durante el ciclo de vida de instalación del service worker, se abre la caché offline-fallbacks y se agrega el array de resguardos sin conexión a la caché.

import { setCatchHandler } from 'workbox-routing';

// Warm the cache when the service worker installs
self.addEventListener('install', event => {
  const files = ['/offline.html']; // you can add more resources here
  event.waitUntil(
    self.caches.open('offline-fallbacks')
        .then(cache => cache.addAll(files))
  );
});

Luego, en setCatchHandler(), se determina el destino de la solicitud que arrojó un error y se abre la caché de offline-fallbacks. Si el destino es un documento, el contenido del resguardo sin conexión se le muestra al usuario. Si no existe, o el destino no es un documento (como una imagen o una hoja de estilo), se muestra una respuesta de error. Puedes extender este patrón no solo para los documentos, sino también para las imágenes, los videos, las fuentes o cualquier cosa que desees proporcionar como resguardo sin conexión.

// Respond with the fallback if a route throws an error
setCatchHandler(async (options) => {
  const destination = options.request.destination;
  const cache = await self.caches.open('offline-fallbacks');
  if (destination === 'document') {
    return (await cache.match('/offline.html')) || Response.error();
  }
  return Response.error();
});

Plantillas

Varios patrones de enrutamiento y almacenamiento en caché, como las navegaciones de NetworkFirst y los resguardos sin conexión, son lo suficientemente comunes como para encapsularlos en recetas reutilizables. Revisa las recetas workbox-recipes, ya que pueden ayudarte si ofrecen una solución adecuada para tu arquitectura. Por lo general, están disponibles como una línea de código que debes agregar al código de tu service worker.

Almacenamiento en caché y actualización de elementos

Almacenar los recursos en caché también implica actualizarlos. Workbox te ayuda a actualizar los recursos de la manera que prefieras. Por ejemplo, puedes mantenerlos actualizados si cambian en el servidor o esperar hasta que tengas una nueva versión de tu app. Obtendrás más información sobre las actualizaciones en el capítulo Actualizaciones.

Juega con Workbox

Puedes jugar con Workbox de inmediato a través del siguiente codelab:

Recursos