Cómo migrar de Workbox v5 a v6

Esta guía se enfoca en los cambios rotundos que se presentan en Workbox v6, con ejemplos de los cambios que tendrías que hacer al actualizar desde Workbox v5.

Cambios rotundos

núcleo de la caja de trabajo

El método skipWaiting() en workbox-core ya no agregará un controlador install y equivale a solo llamar a self.skipWaiting().

A partir de ahora, usa self.skipWaiting() en su lugar, ya que es probable que se quite skipWaiting() en Workbox v7.

almacenamiento previo en caché en caja de trabajo

  • Los documentos HTML de origen cruzado para las URLs que corresponden a un redireccionamiento HTTP ya no se pueden utilizar para satisfacer una solicitud de navegación con workbox-precaching. Esta situación suele ser poco común.
  • Ahora workbox-precaching ignora el parámetro de consulta de URL fbclid cuando se busca una respuesta almacenada en caché previamente para una solicitud determinada.
  • El constructor PrecacheController ahora toma un objeto con propiedades específicas como su parámetro, en lugar de una string. Este objeto admite las siguientes propiedades: cacheName (que cumple el mismo propósito que la string que se pasó al constructor en la versión 5), plugins (reemplaza al método addPlugins() de la versión 5) y fallbackToNetwork (reemplaza a la opción similar que se pasó a createHandler() y `createHandlerBoundToURL() en la versión 5).
  • Los métodos install() y activate() de PrecacheController ahora toman exactamente un parámetro, que se debe establecer en un InstallEvent o ActivateEvent correspondientes, respectivamente.
  • Se quitó el método addRoute() de PrecacheController. En su lugar, se puede usar la nueva clase PrecacheRoute para crear una ruta que luego puedas registrar.
  • Se quitó el método precacheAndRoute() de PrecacheController. (Todavía existe como un método auxiliar estático que el módulo workbox-precaching exporta. Se quitó porque en su lugar se puede usar PrecacheRoute.
  • Se quitó el método createMatchCalback() de PrecacheController. En su lugar, se puede usar el nuevo PrecacheRoute.
  • Se quitó el método createHandler() de PrecacheController. En su lugar, se puede usar la propiedad strategy del objeto PrecacheController para controlar solicitudes.
  • Ya se quitó la exportación estática createHandler() del módulo workbox-precaching. En su lugar, los desarrolladores deberían construir una instancia de PrecacheController y usar su propiedad strategy.
  • La ruta registrada con precacheAndRoute() ahora es una ruta "real" que usa la clase Router de workbox-routing de forma interna. Esto puede generar un orden de evaluación diferente de tus rutas si intercalas llamadas a registerRoute() y precacheAndRoute().

enrutamiento de caja de trabajo

El método setDefaultHandler() ahora toma un segundo parámetro opcional que corresponde al método HTTP al que se aplica, y se establece de forma predeterminada como 'GET'.

  • Si usas setDefaultHandler() y todas tus solicitudes son GET, no es necesario realizar ningún cambio.
  • Si tienes alguna solicitud que no es GET (POST, PUT, etcétera), haz lo siguiente: setDefaultHandler() ya no hará que esas solicitudes coincidan.

Configuración de compilación

La opción mode para los modos getManifest y injectManifest en workbox-build y workbox-cli no estaba diseñada para ser compatible y se quitó. Esto no se aplica a workbox-webpack-plugin, que admite mode en su complemento InjectManifest.

Las herramientas de compilación requieren Node.js v10 o versiones posteriores

Las versiones de Node.js anteriores a la v10 ya no son compatibles con workbox-webpack-plugin, workbox-build ni workbox-cli. Si estás ejecutando una versión de Node.js anterior a la v8, actualiza el entorno de ejecución a una versión compatible.

Nuevas mejoras

estrategias-de-caja de trabajo

Workbox v6 presenta una nueva manera para que los desarrolladores externos definan sus propias estrategias de Workbox. Esto garantiza que los desarrolladores externos tengan la capacidad de extender Workbox de maneras que satisfagan por completo sus necesidades.

Nueva clase básica de estrategia

En la versión 6, todas las clases de estrategia de Workbox deben extender la nueva clase base Strategy. Todas las estrategias integradas se reescribieron para respaldarlo.

La clase base Strategy es responsable de dos elementos principales:

  • Invocar devoluciones de llamada del ciclo de vida del complemento comunes a todos los controladores de estrategia (p. ej., cuando comienzan, responden y finalizan)
  • Crear una instancia de “controlador”, que pueda administrar el estado de cada solicitud individual que controle una estrategia

Nueva clase "handler"

Anteriormente, teníamos módulos internos que llamaban fetchWrapper y cacheWrapper, que (como su nombre indica) unen las diversas APIs de recuperación y caché con hooks en su ciclo de vida. Este es el mecanismo que actualmente permite que funcionen los complementos, pero no está expuesto a los desarrolladores.

La nueva clase "handler", StrategyHandler, expondrá estos métodos para que las estrategias personalizadas puedan llamar a fetch() o cacheMatch() y tener los complementos agregados a la instancia de estrategia que se hayan invocado automáticamente.

Esta clase también permitiría a los desarrolladores agregar sus propias devoluciones de llamada personalizadas de ciclo de vida que podrían ser específicas de sus estrategias, y que "simplemente funcionarían" con la interfaz del complemento existente.

Nuevo estado del ciclo de vida del complemento

En Workbox v5, los complementos no tienen estado. Esto significa que si una solicitud de /index.html activa las devoluciones de llamada requestWillFetch y cachedResponseWillBeUsed, esas dos devoluciones de llamada no tendrán forma de comunicarse entre sí ni de saber que se activaron por la misma solicitud.

En la versión 6, todas las devoluciones de llamada del complemento también recibirán un nuevo objeto state. Este objeto de estado será único para este objeto de complemento en particular y para esta invocación de estrategia en particular (es decir, la llamada a handle()). Esto permite a los desarrolladores escribir complementos en los que una devolución de llamada puede hacer algo condicionalmente en función de lo que hizo otra devolución de llamada en el mismo complemento (p. ej., calcular el delta de tiempo entre la ejecución de requestWillFetch y fetchDidSucceed o fetchDidFail).

Nuevas devoluciones de llamada del ciclo de vida del complemento

Se agregaron nuevas devoluciones de llamada del ciclo de vida del complemento para permitir que los desarrolladores aprovechen al máximo el estado del ciclo de vida del complemento:

  • handlerWillStart: Se llama antes de que cualquier lógica del controlador comience a ejecutarse. Esta devolución de llamada se puede usar para establecer el estado inicial del controlador (p.ej., registrar la hora de inicio).
  • handlerWillRespond: Se llama antes de que el método handle() de las estrategias muestre una respuesta. Esta devolución de llamada se puede usar para modificar esa respuesta antes de mostrarla a un controlador de rutas o a otra lógica personalizada.
  • handlerDidRespond: Se lo llama después de que el método handle() de la estrategia muestra una respuesta. Esta devolución de llamada se puede usar para registrar los detalles de la respuesta final, p.ej., después de los cambios realizados por otros complementos.
  • handlerDidComplete: Se llama después de que se establezcan todas las promesas de por vida útil agregadas al evento desde la invocación de esta estrategia. Esta devolución de llamada se puede usar para informar sobre cualquier dato que deba esperar hasta que el controlador finalice para calcular (p.ej., estado de acierto de caché, latencia de caché, latencia de red).
  • handlerDidError: Se llama si el controlador no pudo proporcionar una respuesta válida de ninguna fuente. Esta devolución de llamada se puede usar para proporcionar contenido de "resguardo" como alternativa a un error de red.

Los desarrolladores que implementan sus propias estrategias personalizadas no tienen que preocuparse por invocar estas devoluciones de llamada por sí mismos, ya que todo se controla mediante una nueva clase base Strategy.

Tipos de TypeScript más precisos para los controladores

Se normalizaron las definiciones de TypeScript para varios métodos de devolución de llamada. Esto debería ofrecer una mejor experiencia a los desarrolladores que usan TypeScript y escriben su propio código para implementar o llamar a controladores.

ventana-cuadro de trabajo

Nuevo método messageSkipWaiting()

Se agregó un nuevo método, messageSkipWaiting(), al módulo workbox-window para simplificar el proceso de indicar al service worker “en espera” que se active. Esto ofrece algunas mejoras:

  • Llama a postMessage() con el cuerpo del mensaje estándar de facto, {type: 'SKIP_WAITING'}, que un service worker generado por Workbox verifica para activar skipWaiting().
  • Elige el service worker correcto en "espera" para publicar este mensaje, incluso si no es el mismo service worker con el que se registró workbox-window.

Eliminación de eventos "externos" para dar lugar a una propiedad isExternal.

Se quitaron todos los eventos "external" en workbox-window, en lugar de los eventos "normales" con una propiedad isExternal establecida en true. De esta manera, los desarrolladores a quienes les interesa esta distinción aún pueden detectarla, y los desarrolladores que no necesitan saberlo pueden ignorar la propiedad.

Receta más limpia "Ofrecer que los usuarios vuelvan a cargar la página"

Gracias a los dos cambios anteriores, la receta "Ofrecer que los usuarios vuelvan a cargar la página" se puede simplificar:

MULTI_LINE_CODE_PLACEHOLDER_0

enrutamiento de caja de trabajo

Se pasa un parámetro booleano nuevo, sameOrigin, a la función matchCallback que se usa en workbox-routing. Se establece como true si la solicitud es para una URL del mismo origen y falso en caso contrario.

Esto simplifica algunos códigos estándar comunes:

MULTI_LINE_CODE_PLACEHOLDER_1

matchOptions en workbox-expiration

Ahora puedes configurar matchOptions en workbox-expiration, que luego se pasará como CacheQueryOptions a la llamada cache.delete() subyacente (la mayoría de los desarrolladores no necesitarán hacer esto).

almacenamiento previo en caché en caja de trabajo

Usa estrategias de caja de trabajo

Se reescribió workbox-precaching para usar workbox-strategies como base. Esto no debería generar cambios rotundos y debería generar una mejor coherencia a largo plazo en cuanto a la forma en que los dos módulos acceden a la red y a la caché.

El almacenamiento previo en caché ahora procesa las entradas una por una, no de forma masiva

Se actualizó workbox-precaching para que solo se solicite y almacene en caché una entrada del manifiesto de precaché a la vez, en lugar de intentar solicitarlas y almacenarlas en caché todas a la vez (dejándolas en el navegador para determinar cómo limitarlas).

Esto debería reducir la probabilidad de errores net::ERR_INSUFFICIENT_RESOURCES durante el almacenamiento previo en caché y, además, reducir la contención de ancho de banda entre este tipo de almacenamiento y las solicitudes simultáneas que realiza la app web.

PrecacheFallbackPlugin facilita el resguardo sin conexión

workbox-precaching ahora incluye un PrecacheFallbackPlugin, que implementa el nuevo método de ciclo de vida handlerDidError que se agregó en la versión 6.

Esto facilita la especificación de una URL almacenada en caché como "resguardo" para una estrategia determinada cuando una respuesta no estaría disponible de otra manera. El complemento se encargará de construir correctamente la clave de caché correcta para la URL almacenada en caché previamente, incluidos los parámetros de revisión que sean necesarios.

A continuación, se muestra un ejemplo de cómo usarlo para responder con un /offline.html prealmacenado en caché cuando la estrategia NetworkOnly no puede generar una respuesta para una solicitud de navegación; en otras palabras, mostrar una página HTML sin conexión personalizada:

MULTI_LINE_CODE_PLACEHOLDER_2

precacheFallback en almacenamiento en caché del entorno de ejecución

Si usas generateSW para crear un service worker en lugar de escribir el service worker de forma manual, puedes usar la nueva opción de configuración precacheFallback en runtimeCaching para lograr lo mismo:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

Cómo obtener ayuda

Prevemos que la mayoría de las migraciones serán sencillas. Si tienes problemas que no se tratan en esta guía, abre un problema en GitHub.