Migra de Workbox v2 a v3

Esta guía se enfoca en los cambios rotundos que se presentan en Workbox v3, con ejemplos de los cambios que debes realizar cuando actualizas desde una configuración de Workbox v2.

Si actualmente usas la combinación heredada de sw-precache y sw-toolbox y quieres hacer la transición a Workbox por primera vez, consulta esta guía de migración diferente que te ayudará.

Fondo de v3

La versión v3 de Workbox representa una refactorización significativa de la base de código existente. Los objetivos generales son los siguientes:

  • Minimiza el tamaño de la Caja de trabajo. Se redujo la cantidad de código del entorno de ejecución del service worker que se descarga y ejecuta. En lugar de habilitar un paquete monolítico para todos, solo se importará en el entorno de ejecución el código de las funciones específicas que usas.
  • Workbox tiene una CDN. Proporcionamos un hosting de CDN basado en Google Cloud Storage y totalmente compatible como la opción canónica para acceder a las bibliotecas del entorno de ejecución de Workbox, lo que facilita la puesta en marcha de Workbox.
  • Mejor depuración y registros. Se mejoró considerablemente la experiencia de depuración y registro. Los registros de depuración están habilitados de forma predeterminada cada vez que se usa Workbox desde un origen localhost y todos los registros y las aserciones se quitan de las compilaciones de producción. Un ejemplo del registro de depuración que ofrece Workbox v3.
  • Complemento webpack mejorado. workbox-webpack-plugin se integra más estrechamente con el proceso de compilación del paquete web, lo que permite un caso de uso sin configuración cuando deseas almacenar previamente en caché todos los elementos de la canalización de compilación.

Para lograr estos objetivos y realizar una limpieza de algunos aspectos de la interfaz anterior que resultaron incómodos o que condujeron a antipatrones, fue necesario introducir una serie de cambios rotundos en la versión v3.

Cambios rotundos

Configuración de compilación

Los siguientes cambios afectan el comportamiento de todas nuestras herramientas de compilación (workbox-build, workbox-cli, workbox-webpack-plugin), que comparten un conjunto común de opciones de configuración.

  • El nombre del controlador 'fastest' era válido anteriormente y se trató como un alias para 'staleWhileRevalidate' cuando se configuraba runtimeCaching. Ya no es válida, y los desarrolladores deberían comenzar a usar directamente 'staleWhileRevalidate'.
  • Se actualizaron varios nombres de propiedades runtimeCaching.options y hay una validación de parámetros adicional implementada, lo que provocará que una compilación falle si se usa una configuración no válida. Consulta la documentación de runtimeCaching para obtener una lista de las opciones que se admiten actualmente.

sincronización en segundo plano de la caja de trabajo

  • El parámetro de configuración maxRetentionTime ahora se interpreta como una cantidad de minutos, en lugar de una cantidad de milisegundos.
  • Ahora hay una cadena obligatoria, que representa el nombre de la cola, que se debe pasar como el primer parámetro cuando se construye el complemento o la clase independiente. (Anteriormente, se pasaba como una propiedad de las opciones). Consulta la documentación de la plataforma de API actualizada.

workbox-broadcast-cache-update

  • Ahora hay una cadena obligatoria, que representa el nombre del canal, que se debe pasar como primer parámetro cuando se construye el complemento o la clase independiente.

Por ejemplo, en la v2, inicializarás la clase Plugin de la siguiente manera:

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

El uso equivalente en la v3 es el siguiente:

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

Consulta la documentación de la plataforma de API actualizada.

compilación de la caja de trabajo

  • De forma predeterminada, la coincidencia de patrones glob ahora se realizará con las opciones follow: true (que seguirán a los symlinks) y strict: true (que es menos tolerante a errores "inusuales"). Puedes inhabilitar cualquiera de ellas y volver al comportamiento anterior estableciendo globFollow: false o globStrict: false en la configuración de compilación.
  • Todas las funciones de workbox-build muestran una propiedad adicional, warnings, en las respuestas que muestran. Ahora se permiten algunas situaciones que se trataron como errores fatales en la versión 2, pero se informan a través de warnings, que es un array de cadenas.

En la versión 2, puedes llamar a generateSW de la siguiente manera:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

Si bien puedes usar el mismo código en la v3, es una buena idea comprobar si hay warnings y registrarlas:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • Los desarrolladores que escribieron sus propias funciones ManifestTransform personalizadas en la versión 2 deben mostrar el array de manifiesto en un objeto (es decir, en lugar de return manifestArray;, debes usar return {manifest: manifestArray};).mEsto permite que tu complemento incluya una propiedad warnings opcional, que debe ser un array de cadenas con información de advertencia recuperable.

Si escribes un ManifestTransform personalizado en la versión 2, usa el siguiente código:

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

tiene un equivalente v3 de:

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};
  • Se cambió el nombre de la función getFileManifestEntries() por getManifest(), y la promesa que se muestra ahora incluye información adicional sobre las URLs que se almacenaron en caché previamente.

Código como el siguiente en la v2:

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

se puede reescribir en la v3 de la siguiente manera:

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • Se quitó la función generateFileManifest(). Se recomienda a los desarrolladores que llamen a getManifest() y usen su respuesta para escribir datos en el disco en el formato adecuado.

Vencimiento-de-caché-de-cuadro de trabajo

  • La API del complemento sigue siendo la misma, que es el modo que la mayoría de los desarrolladores terminarán usando. Sin embargo, hay cambios significativos en la API que afectan a los desarrolladores que la usan como clase independiente. Consulta la documentación de la plataforma de API actualizada.

workbox-cli

Los desarrolladores pueden ejecutar la CLI con la marca --help para un conjunto completo de parámetros compatibles.

  • Se quitó la compatibilidad con el alias workbox-cli para la secuencia de comandos binaria. Ahora solo se puede acceder al objeto binario como workbox.
  • Se cambió el nombre de los comandos generate:sw y inject:manifest de la versión 2 a generateSW y injectManifest en la versión 3.
  • En la v2, se supone que el archivo de configuración predeterminado (que se usa cuando no se proporcionó uno de forma explícita) es workbox-cli-config.js en el directorio actual. En la versión 3, es workbox-config.js.

En conjunto, esto significa que en la versión 2 sucede lo siguiente:

$ workbox inject:manifest

ejecutaría el proceso de compilación "inyectar manifiesto", utilizando una configuración leída de workbox-cli-config.js, y en v3:

$ workbox injectManifest

hará lo mismo, pero leerá la configuración desde workbox-config.js.

almacenamiento previo en caché de la caja de trabajo

  • Anteriormente, el método precache() realizaba las modificaciones de la caché y configuró el enrutamiento para entregar entradas almacenadas en caché. Ahora, precache() solo modifica las entradas de caché, y se expuso un nuevo método, addRoute(), a fin de registrar una ruta para entregar esas respuestas almacenadas en caché. Los desarrolladores que deseen la funcionalidad anterior dos en uno pueden cambiar a llamar a precacheAndRoute().
  • Varias opciones que se configuraban mediante el constructor WorkboxSW ahora se pasan como el parámetro options en workbox.precaching.precacheAndRoute([...], options). Los valores predeterminados de esas opciones, cuando no se configuran, se enumeran en los documentos de referencia.
  • De forma predeterminada, las URLs que no tengan ninguna extensión de archivo se verificarán automáticamente para verificar si coinciden con una entrada de caché que contenga una extensión .html. Por ejemplo, si se realiza una solicitud para /path/to/index (que no se almacena en caché previamente) y hay una entrada almacenada en caché previamente para /path/to/index.html, se usará esa entrada. Los desarrolladores pueden inhabilitar este nuevo comportamiento configurando {cleanUrls: false} cuando pasen las opciones a workbox.precaching.precacheAndRoute().
  • workbox-broadcast-update ya no se configurará automáticamente para anunciar actualizaciones de caché para elementos prealmacenados en caché.

El siguiente código de v2:

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

tiene un equivalente v3 de:

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

enrutamiento de cuadros de trabajo

  • Los desarrolladores que antes usaban workbox-routing a través del espacio de nombres workbox.router.* de un objeto WorkboxSW deben cambiar al espacio de nombres nuevo, workbox.routing.*.
  • Las rutas ahora se evalúan en el orden de registro primero que se marcó como ganador. Este es el orden opuesto de la evaluación de Route que se usó en la v2, en la que tendría prioridad la Route que se registró por última vez.
  • Se quitaron la clase ExpressRoute y la compatibilidad con los comodines de "estilo exprés". Esto reduce considerablemente el tamaño de workbox-routing. Las strings usadas como el primer parámetro de workbox.routing.registerRoute() ahora se tratarán como coincidencias exactas. Las coincidencias parciales o comodín deben controlarse mediante RegExp; el uso de cualquier RegExp que coincida con una parte de la URL de la solicitud o con toda la URL puede activar una ruta.
  • Se quitó el método auxiliar addFetchListener() de la clase Router. Los desarrolladores pueden agregar su propio controlador fetch de forma explícita o usar la interfaz que proporciona workbox.routing, que creará implícitamente un controlador fetch para ellos.
  • Se quitaron los métodos registerRoutes() y unregisterRoutes(). Las versiones de esos métodos que operan en un solo Route no se modificaron, y los desarrolladores que necesiten registrar o cancelar el registro de varias rutas a la vez deben realizar una serie de llamadas a registerRoute() o unregisterRoute().

El siguiente código de v2:

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

tiene un equivalente v3 de:

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

Workbox-strategies (anteriormente conocidas como workbox-runtime-caching)

  • El módulo workbox-runtime-caching ahora se conoce oficialmente como workbox-strategies y se publicó en npm con su nuevo nombre.
  • El uso del vencimiento de la caché en una estrategia sin proporcionar también un nombre de la caché ya no es válido. En la versión 2, esto era posible:
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

Esto provocaría que las entradas venzan en la caché predeterminada, lo cual es inesperado. En la versión 3, se requiere un nombre de caché:

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • Se cambió el nombre del método de ciclo de vida de cacheWillMatch a cachedResponseWillBeUsed. Este no debería ser un cambio visible para los desarrolladores, a menos que hayan escrito sus propios complementos que reaccionen a cacheWillMatch.
  • Cambió la sintaxis para especificar complementos cuando se configura una estrategia. Cada complemento debe estar enumerado explícitamente en la propiedad plugins de la configuración de la estrategia.

El siguiente código de v2:

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

tiene un equivalente v3 de:

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

Puedes obtener más información en la guía "Cómo usar complementos".

Workbox-sw

  • De forma interna, workbox-sw se reescribió para que sea una interfaz de "cargador" liviana, que toma alguna configuración básica y es responsable de extraer los otros módulos que se necesitan durante el tiempo de ejecución. En lugar de construir una instancia nueva de la clase WorkboxSW, los desarrolladores interactuarán con una instancia existente que se expone automáticamente en el espacio de nombres global.

Anteriormente en la versión 2:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

En la v3, solo tienes que importar la secuencia de comandos workbox-sw.js, y una instancia lista para usar estará disponible automáticamente en el espacio de nombres global como workbox:

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • skipWaiting y clientsClaim ya no son opciones que se pasan al constructor WorkboxSW. En cambio, se cambiaron a los métodos workbox.clientsClaim() y workbox.skipWaiting().
  • La opción handleFetch que antes se admitía en el constructor v2 ya no se admite en v3. Los desarrolladores que necesiten una funcionalidad similar para probar su service worker sin que se invoque ningún controlador de recuperación pueden usar la opción "Bypass for network" disponible en las herramientas para desarrolladores de Chrome.
La opción Omitir para red en las Herramientas para desarrolladores de Chrome.

complemento-web-pack-de-workbox

El complemento se reescribió considerablemente y, en muchos casos, se puede usar en el modo de "sin configuración". Consulta la documentación de la plataforma de API actualizada.

  • La API ahora expone dos clases: GenerateSW y InjectManifest. Esto hace que el cambio entre modos sea explícito, en comparación con el comportamiento de la v2, en el que el comportamiento cambió en función de la presencia de swSrc.
  • De forma predeterminada, los elementos de la canalización de compilación del webpack se almacenarán previamente en caché y ya no es necesario configurar globPatterns. El único motivo para seguir usando globPatterns es si necesitas almacenar previamente en caché recursos que no se incluyen en la compilación de tu paquete web. En general, cuando migres al complemento v3, deberás comenzar quitando toda la configuración anterior basada en glob y solo volver a agregarla si la necesitas específicamente.

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 para informarnos al respecto.