Esta guía se centra en los cambios rotundos introducidos en Workbox v5, con ejemplos de los cambios que debes realizar cuando actualizas desde Workbox v4.
Cambios rotundos
Se cambiaron los nombres de las clases de complementos
Varios paquetes de Workbox v4 incluían clases llamadas Plugin
. En la v5, se cambió el nombre de esas clases para que sigan el identificador del paquete de patrón + Plugin
:
BackgroundSyncPlugin
BroadcastUpdatePlugin
CacheableResponsePlugin
ExpirationPlugin
RangeRequestsPlugin
Este cambio de nombre se aplica ya sea que uses las clases a través de importaciones de módulos o a través de los espacios de nombres workbox.*
.
Punto de reemplazo predeterminado del manifiesto de almacenamiento en caché
Anteriormente, cuando se usaba una de las herramientas de compilación en el modo "insertar manifiesto", se verificaba el archivo de service worker de origen en busca de precacheAndRoute([])
, y se usaba ese array vacío []
como marcador de posición para el punto en el que se insertaba el manifiesto de almacenamiento en caché.
En Workbox v5, cambió la lógica de reemplazo y ahora se usa self.__WB_MANIFEST
de forma predeterminada como punto de inyección.
// v4:
precacheAndRoute([]);
// v5:
precacheAndRoute(self.__WB_MANIFEST);
Como se indicó en este debate, creemos que este cambio proporciona una experiencia más simple y, al mismo tiempo, brinda a los desarrolladores más control sobre cómo se usa el manifiesto insertado dentro del código de service worker personalizado. Si es necesario, puedes cambiar esta cadena de reemplazo mediante la opción de configuración injectionPoint
.
Cambios en la ruta de navegación
Dos opciones que antes se admitían para las rutas de navegación, blacklist
y whitelist
, ahora se llaman denylist
y allowlist
.
Anteriormente, workbox-routing
admitía un método, registerNavigationRoute()
, que, de forma interna, realizaba dos acciones:
- Se detectó si un evento
fetch
determinado tenía o no unmode
de'navigate'
. - Si es así, responde a esa solicitud con el contenido de una URL codificada previamente almacenada en caché, independientemente de la URL a la que se esté navegando.
Este es un patrón común que se usa cuando se implementa la arquitectura de shell de app.
El segundo paso, generar una respuesta leyendo desde la caché, no está dentro de lo que consideramos las responsabilidades de workbox-routing
. En cambio, lo vemos como una funcionalidad que debería ser parte de workbox-precaching
, a través de un método nuevo: createHandlerBoundToURL()
. Este nuevo método puede funcionar junto con la clase NavigationRoute
existente en workbox-routing
para lograr la misma lógica.
Si usas la opción navigateFallback
en uno de los archivos "generate SW" de la herramienta de compilación. el cambio se realizará automáticamente. Si configuraste previamente las opciones navigateFallbackBlacklist
o navigateFallbackWhitelist
, cámbialas a navigateFallbackDenylist
o navigateFallbackAllowlist
, respectivamente.
Si usas el modo "insertar manifiesto" o simplemente escribes el trabajador del servicio por tu cuenta, y tu trabajador del servicio de Workbox v4 llama a registerNavigationRoute()
directamente, deberás hacer un cambio en tu código para obtener el comportamiento equivalente.
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
Ya no necesitas llamar a getCacheKeyForURL()
, dado que createHandlerBoundToURL()
se encargará de eso.
Se quitó makeRequest() de workbox-strategies
Llamar a makeRequest()
equivale, en su mayoría, a llamar a handle()
en una de las clases workbox-strategy
. Las diferencias entre los dos métodos eran tan leves que no tenía sentido mantener ambos. Los desarrolladores que llamaron a makeRequest()
deberían poder cambiar a handle()
sin ningún otro cambio:
// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});
// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});
En la versión 5, handle()
trata a request
como un parámetro obligatorio y no recurrirá a event.request
. Asegúrate de pasar una solicitud válida cuando llames a handle()
.
workbox-broadcast-update siempre usa postMessage()
En la versión 4, la biblioteca workbox-broadcast-update
usaría de forma predeterminada la API de Broadcast Channel para enviar mensajes cuando fuera compatible y usaría postMessage()
solo cuando Broadcast Channel no fuera compatible.
Nos dimos cuenta de que tener que escuchar dos fuentes potenciales de mensajes entrantes hacía que escribir código del cliente fuera demasiado complicado. Además, en algunos navegadores, las llamadas postMessage()
del trabajador de servicio que se envían a las páginas del cliente se almacenan en búfer automáticamente hasta que se configura un objeto de escucha de eventos message
. Con la API de Broadcast Channel, no se produce almacenamiento en búfer, y los mensajes transmitidos solo se descartan si se envían antes de que la página de un cliente esté lista para recibirlos.
Por estos motivos, cambiamos workbox-broadcast-update
para que siempre use postMessage()
en la versión 5. Los mensajes se envían de uno en uno a todas las páginas del cliente dentro del alcance del trabajador de servicio actual.
Para adaptarse a este nuevo comportamiento, puedes quitar cualquier código que hayas tenido en las páginas cliente que crearon instancias de BroadcastChannel
y, en su lugar, configurar un objeto de escucha de eventos message
en navigator.serviceWorker
:
// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
});
// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
}
});
Los usuarios de workbox-window
no deberían necesitar realizar ningún cambio, ya que se actualizó su lógica interna para escuchar las llamadas de postMessage()
.
Las herramientas de compilación requieren Node.js v8 o una versión posterior
Las versiones anteriores a la v8 de Node.js ya no son compatibles con workbox-webpack-plugin
, workbox-build
ni workbox-cli
. Si ejecutas una versión de Node.js anterior a la 8, actualiza tu entorno de ejecución a una versión compatible.
workbox-webpack-plugin requiere webpack v4 o superior,
Si usas workbox-webpack-plugin
, actualiza la configuración de webpack para usar, al menos, webpack v4.
Revisión de las opciones de herramientas de compilación
Ya no se admiten algunos parámetros de configuración de workbox-build
, workbox-cli
y workbox-webpack-plugin
. Por ejemplo, generateSW
siempre creará un paquete de entorno de ejecución de Workbox local para ti, por lo que la opción importWorkboxFrom
ya no tiene sentido.
Consulta la documentación de la herramienta correspondiente para conocer las listas de opciones admitidas.
Eliminación de generateSWString de workbox-build
Se quitó el modo generateSWString
de workbox-build
. Esperamos que el impacto sea mínimo, ya que workbox-webpack-plugin
lo utilizó principalmente de forma interna.
Cambios opcionales
Usa importaciones de módulos
Si bien este cambio es a) opcional y b) técnicamente era posible cuando se usaba Workbox v4, el mayor cambio que anticipamos al pasar a la v5 es un modelo en el que creas tu propio service worker empaquetado importando los módulos de Workbox. Este enfoque es una alternativa para llamar a importScripts('/path/to/workbox-sw.js')
en la parte superior de tu trabajador de servicio y usar Workbox a través del espacio de nombres workbox.*
.
Si usas una de las herramientas de compilación (workbox-webpack-plugin
, workbox-build
, workbox-cli
) en "generate SW" , este cambio se implementará automáticamente. Todas esas herramientas generarán un paquete local personalizado del entorno de ejecución de Workbox junto con el código real necesario para implementar la lógica de tu service worker. En este caso, ya no hay dependencia en workbox-sw
ni en la copia de CDN de Workbox. Según el valor de la configuración de inlineWorkboxRuntime
, el entorno de ejecución de Workbox se dividirá en un archivo independiente que se debe implementar junto con tu trabajador de servicio (cuando se establece en false
, que es la configuración predeterminada) o se incluirá intercalado junto con la lógica del trabajador de servicio (cuando se establece en true
).
Si usas las herramientas de compilación en el modo "insertar manifiesto" o no usas las herramientas de compilación de Workbox, puedes obtener más información para crear tu propio paquete de tiempo de ejecución de Workbox en la guía existente Cómo usar empaquetadores (webpack/Rollup) con Workbox.
La documentación y los ejemplos de la versión 5 se escribieron asumiendo la sintaxis de importación de módulos, aunque el espacio de nombres workbox.*
seguirá siendo compatible con Workbox v5.
Lee las respuestas previamente almacenadas en caché
Algunos desarrolladores deben leer respuestas almacenadas en caché previamente directamente desde la caché, en lugar de usarlas de forma implícita a través del método precacheAndRoute()
. Un patrón común en la v4 sería obtener primero la clave de caché específica para la versión actual de un recurso almacenado previamente en caché y, luego, pasar esa clave junto con el nombre de la caché de la caché previa a caches.match()
para obtener la Response
.
Para simplificar este proceso, workbox-precaching
en la versión 5 admite un nuevo método equivalente, matchPrecache()
:
// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';
const cachedResponse = await caches.match(
getCacheKeyForURL(`/somethingPrecached`),
{
cacheName: cacheNames.precache,
}
);
// v5:
import {matchPrecache} from 'workbox-precaching';
const cachedResponse = await matchPrecache(`/somethingPrecached`);
Adopción de TypeScript
En la versión 5, las bibliotecas de entorno de ejecución de Workbox se escriben en TypeScript. Si bien seguiremos publicando módulos y paquetes de JavaScript transpilados para los desarrolladores que no hayan adoptado TypeScript, si usas TypeScript, deberías beneficiarte de la información de tipos precisa y siempre actualizada directamente desde el proyecto de Workbox.
Ejemplo de migración
Esta confirmación ilustra una migración bastante compleja, con comentarios intercalados. Utiliza Rollup para incluir un un entorno de ejecución personalizado de Workbox en el service worker final, en lugar de cargarlo desde la CDN.
Si bien no abarca todos los cambios rotundos, a continuación, te mostramos el antes y el después de actualizar un archivo de service worker de la versión 4 a la 5, incluido un cambio a TypeScript.
Cómo obtener ayuda
Prevemos que la mayoría de las migraciones serán sencillas. Si tienes problemas que no se abordan en esta guía, abre un problema en GitHub para informarnos al respecto.