Esta guía se centra en los cambios rotundos introducidos 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 sw-precache
/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 la v3
La versión 3 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 a todos en un paquete monolítico, solo se importará en el entorno de ejecución el código de las funciones específicas que estés usando.
- Workbox tiene una CDN. Proporcionamos un hosting de CDN basado en Google Cloud Storage completamente 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ó ampliamente 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. - Se mejoró el complemento webpack.
workbox-webpack-plugin
se integra más estrechamente al proceso de compilación del paquete web, lo que permite un caso de uso sin configuración cuando se desea almacenar en caché previamente todos los elementos en la canalización de compilación.
Para lograr estos objetivos y limpiar algunos aspectos de la interfaz anterior que se sentían incómodos o condujeron a antipatrones, fue necesario incorporar 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'
durante la configuración deruntimeCaching
. Ya no es válida, y los desarrolladores deben comenzar a usar'staleWhileRevalidate'
directamente. - Se actualizaron varios nombres de la propiedad
runtimeCaching.options
, y se está realizando una validación de parámetros adicional que provocará que la compilación falle si se usa una configuración no válida. Consulta la documentación deruntimeCaching
para obtener una lista de las opciones admitidas actualmente.
workbox-background-sync
- El parámetro de configuración
maxRetentionTime
ahora se interpreta como un número 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 para conocer 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 el primer parámetro cuando se construye el complemento o la clase independiente.
Por ejemplo, en la v2, debes inicializar 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 para conocer la plataforma de API actualizada.
workbox-build
- De forma predeterminada, ahora se realizará la coincidencia de patrones de
glob
con las opcionesfollow: true
(que seguirán a los symlinks) ystrict: true
(que es menos tolerante a errores “inusuales”). Puedes inhabilitar ambos y volver al comportamiento anterior si establecesglobFollow: false
oglobStrict: false
en la configuración de compilación. - Todas las funciones de
workbox-build
muestran una propiedad adicional,warnings
, en las respuestas que muestran. Algunas situaciones que se trataron como errores fatales en la versión 2 ahora están permitidas, pero se informan a través dewarnings
, que es un array de cadenas.
En la v2, 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, te recomendamos que verifiques si hay warnings
y que los registres:
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 v2 deben mostrar el array de manifiesto en un objeto (es decir, en lugar dereturn manifestArray;
, debes usarreturn {manifest: manifestArray};
).mEsto permite que tu complemento incluya una propiedadwarnings
opcional, que debe ser un array de cadenas con información de advertencias recuperables.
Si escribieras un ManifestTransform
personalizado en la versión 2, usarías 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()
agetManifest()
, y la promesa que se muestra ahora incluye información adicional sobre las URLs que se almacenaron en caché previamente.
En la v2, se incluye un código como el siguiente:
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 que los desarrolladores llamen agetManifest()
y usen su respuesta para escribir datos en el disco en el formato adecuado.
workbox-cache-expiration
- La API del complemento se mantuvo igual, que es el modo que utilizarán la mayoría de los desarrolladores. Sin embargo, hay cambios significativos en la API que afectan a los desarrolladores que la usan como clase independiente. Consulta la documentación para conocer la plataforma de API actualizada.
workbox-cli
Los desarrolladores pueden ejecutar la CLI con la marca --help
para obtener un conjunto completo de los 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 comoworkbox
. - Los comandos de la v2
generate:sw
yinject:manifest
cambiaron de nombre porgenerateSW
yinjectManifest
en la v3. - En la v2, se suponía que el archivo de configuración predeterminado (que se usaba cuando no se proporcionaba uno explícitamente) era
workbox-cli-config.js
en el directorio actual. En la versión 3, esworkbox-config.js
.
En conjunto, esto significa que en la v2:
$ workbox inject:manifest
ejecuta el "manifiesto de inyección" de compilación mediante una configuración leída de workbox-cli-config.js
, y en la v3:
$ workbox injectManifest
hará lo mismo, pero leerá la configuración desde workbox-config.js
.
almacenamiento previo en caché en la caja de trabajo
- Anteriormente, el método
precache()
realizaba las modificaciones de caché y configuró el enrutamiento para entregar entradas almacenadas en caché. Ahora,precache()
solo modifica las entradas de caché, y se expuso un método nuevo,addRoute()
, para registrar una ruta que entregue esas respuestas almacenadas en caché. Los desarrolladores que deseen la funcionalidad dos en uno anterior pueden llamar aprecacheAndRoute()
. - Varias opciones que se solían configurar a través del constructor
WorkboxSW
ahora se pasan como el parámetrooptions
enworkbox.precaching.precacheAndRoute([...], options)
. Los valores predeterminados para esas opciones, cuando no se configuran, se enumeran en los documentos de referencia. - De forma predeterminada, las URLs que no tengan extensiones de archivo se verificarán automáticamente en busca de coincidencias con una entrada de caché que contenga la extensión
.html
. Por ejemplo, si se realiza una solicitud para/path/to/index
(que no está almacenada en caché previamente) y hay una entrada almacenada en caché previamente para/path/to/index.html
, se usará esa entrada almacenada en caché previamente. Los desarrolladores pueden inhabilitar este comportamiento nuevo configurando{cleanUrls: false}
cuando pasen opciones aworkbox.precaching.precacheAndRoute()
. workbox-broadcast-update
ya no se configurará automáticamente para anunciar actualizaciones de caché de recursos almacenados en caché previamente.
El siguiente código de la versión 2:
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 la caja de trabajo
- Los desarrolladores que antes usaban
workbox-routing
a través del espacio de nombresworkbox.router.*
de un objeto WorkboxSW deben cambiar al espacio de nombres nuevo,workbox.routing.*
. - Las rutas ahora se evalúan en un orden de éxito registrado primero. Este es el orden opuesto a la evaluación de
Route
que se usó en la v2, en la que elRoute
registrado por última vez tendrá prioridad. - Clase
ExpressRoute
y compatibilidad con "estilo Express" se quitaron los comodines. Esto reduce considerablemente el tamaño deworkbox-routing
. Las cadenas que se usan como primer parámetro deworkbox.routing.registerRoute()
ahora se tratarán como coincidencias exactas. LosRegExp
deben controlar las coincidencias parciales o comodines; el uso de cualquierRegExp
que coincida con una parte o la totalidad de la URL de la solicitud puede activar una ruta. - Se quitó el método auxiliar
addFetchListener()
de la claseRouter
. Los desarrolladores pueden agregar su propio controladorfetch
de forma explícita o usar la interfaz proporcionada porworkbox.routing
, que creará implícitamente un controladorfetch
para ellos. - Se quitaron los métodos
registerRoutes()
yunregisterRoutes()
. Las versiones de esos métodos que operan en un soloRoute
no se modificaron, y los desarrolladores que necesitan registrar o cancelar el registro de varias rutas a la vez deben realizar una serie de llamadas aregisterRoute()
ounregisterRoute()
.
El siguiente código de la versión 2:
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()
);
Estrategias de la caja de trabajo (antes conocida como almacenamiento en caché del entorno de ejecución de la caja de trabajo)
- El módulo
workbox-runtime-caching
ahora se conoce oficialmente comoworkbox-strategies
y se publicó elnpm
con su nuevo nombre. - Ya no es válido usar el vencimiento de la caché en una estrategia sin proporcionar también un nombre de caché. En la v2, esto era posible:
workboxSW.strategies.staleWhileRevalidate({
cacheExpiration: {maxEntries: 50},
});
Esto provocaría el vencimiento de las entradas de la caché predeterminada, lo cual es inesperado. En la v3, un nombre de caché se requiere:
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
acachedResponseWillBeUsed
. Este no debería ser un cambio visible para los desarrolladores, a menos que hayan escrito sus propios complementos que reaccionaron acacheWillMatch
. - Se modificó la sintaxis para especificar complementos al configurar una estrategia. Se debe indicar de forma explícita cada complemento en la propiedad
plugins
de la configuración de la estrategia.
El siguiente código de la versión 2:
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 sección "Using Plugins" .
caja-de-trabajo-sw
- De forma interna, se reescribió
workbox-sw
para que fuera un "cargador" ligero. que toma alguna configuración básica y se encarga de extraer los otros módulos que se necesitan en el tiempo de ejecución. En lugar de construir una instancia nueva de la claseWorkboxSW
, los desarrolladores interactuarán con una instancia existente que se expone automáticamente en el espacio de nombres global.
Anteriormente en la v2:
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 debes 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
yclientsClaim
ya no son opciones que se pasan al constructorWorkboxSW
. En cambio, se cambiaron a los métodosworkbox.clientsClaim()
yworkbox.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 invoquen controladores de recuperación pueden usar la opción "Bypass for network" en las Herramientas para desarrolladores de Chrome.
workbox-webpack-plugin
El complemento se reescribió de forma sustancial y, en muchos casos, se puede usar con una "configuración cero". . Consulta la documentación para conocer la plataforma de API actualizada.
- La API ahora expone dos clases:
GenerateSW
yInjectManifest
. 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 deswSrc
. - De forma predeterminada, los elementos de la canalización de compilación del paquete web se almacenarán en caché con anterioridad y ya no es necesario configurar
globPatterns
. El único motivo para seguir usandoglobPatterns
es si necesitas almacenar en caché por adelantado los elementos que no están incluidos en la compilación del paquete web. En general, cuando migres al complemento v3, deberás comenzar quitando toda la configuración basada englob
anterior 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.