Un módulo de Workbox que aún no se ha cubierto mucho en esta documentación es workbox-window
, que es un conjunto de módulos diseñados para ejecutarse en window
. Los objetivos de este módulo son los siguientes:
- Para simplificar el registro y las actualizaciones de los service workers, se ayuda a los desarrolladores a identificar los momentos críticos del ciclo de vida de los service workers y se facilita la respuesta en esos momentos.
- Para evitar que los desarrolladores cometan errores comunes, como registrar un trabajador de servicio en el alcance incorrecto.
- Para simplificar los mensajes entre
window
y el alcance del trabajador de servicio.
Importa y usa workbox-window
La exportación que usarás con mayor frecuencia desde workbox-window
es la clase Workbox
, que puedes importar en Node o desde la CDN en una página web.
Crea un paquete local
Si tu cadena de herramientas incluye un agrupador como webpack o Rollup, puedes empaquetar workbox-window
de forma local.
Primero, instala workbox-window
como una dependencia de producción de tu aplicación:
npm install workbox-window --save
Luego, en el código JavaScript de tu aplicación, puedes import
la clase Workbox
desde workbox-window
:
<script type="module">
import {Workbox} from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Aunque workbox-window
es bastante pequeño, podrías separarlo de la lógica de la aplicación principal de tu sitio web con import
dinámico, lo que puede reducir el tamaño del paquete principal de tu página:
<script type="module">
if ('serviceWorker' in navigator) {
const {Workbox} = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Usa la CDN
Si bien no es el enfoque recomendado, una manera más fácil de usar workbox-window
es importarlo desde una CDN:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Notarás que el elemento <script>
en el ejemplo anterior usa el atributo type="module"
. Esto es obligatorio si deseas usar sentencias import
estáticas en el navegador sin un paso de compilación. Todos los navegadores principales que admiten service workers también admiten módulos de JavaScript, por lo que puedes entregar este código a cualquier navegador, ya que los navegadores más antiguos ignorarán los elementos <script>
con un valor de atributo type
de "module"
.
Registra un service worker
El registro de un service worker con workbox-window
se realiza con el método register
de la clase Workbox
de la siguiente manera:
import {Workbox} from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
Puede parecer que esto es lo mismo que registrar un service worker tú mismo con navigator.serviceWorker.register
. Sin embargo, Workbox.register
se encarga de esperar hasta el evento window
load
antes de registrar el service worker. Esto es conveniente en situaciones en las que se usa el almacenamiento en caché previo para evitar la contención de ancho de banda que puede retrasar el inicio de la página.
Comunicación entre window
y el alcance del trabajador de servicio
Los trabajadores de servicio tienen su propio alcance, independiente de window
, y solo tienen acceso a un subconjunto de las APIs disponibles en window
. Sin embargo, es posible comunicarse entre window
y el trabajador de servicio. workbox-window
permite una comunicación más sencilla entre los dos alcances con el método messageSW
del módulo workbox-window
.
Workbox usa un formato específico para los mensajes, que es un objeto con las siguientes propiedades:
type
es una cadena única obligatoria que identifica el mensaje. El formato debe estar en mayúsculas y tener guiones bajos para separar las palabras (por ejemplo,CACHE_URLS
).meta
es una cadena opcional que representa el nombre del paquete de Workbox que envía el mensaje y, por lo general, se omite.payload
es un parámetro opcional que representa los datos que deseas enviar. Puede ser de cualquier tipo.
A continuación, se muestra un ejemplo de cómo funciona messageSW
, comenzando por el código del service worker:
// sw.js
const SW_VERSION = '1.0.0';
self.addEventListener('message', (event) => {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
});
Y, luego, el siguiente código en tu página web:
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
Hay muchos casos en los que puede ser útil la comunicación entre un trabajador de servicio y window
, como notificar al usuario cuando hay una actualización de trabajador de servicio disponible. Esa receta se basa en un método de ayuda especial para self.skipWaiting
llamado messageSkipWaiting
, que envía un mensaje con un valor type
de SKIP_WAITING
.