Un módulo de Workbox que todavía no recibió mucha cobertura en esta documentación es workbox-window
, que es un conjunto de módulos destinados a ejecutarse en window
. Estos son los objetivos de este módulo:
- Ayudar a los desarrolladores a identificar momentos críticos del ciclo de vida del service worker para simplificar el registro y las actualizaciones de los service workers, lo que facilita responder en esos momentos.
- Para evitar que los desarrolladores cometan errores comunes, como registrar un service worker en el alcance equivocado
- Para simplificar la mensajería entre
window
y el permiso de service worker.
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.
Cómo crear un paquete local
Si tu cadena de herramientas incluye un agrupador como webpack o Rollup, puedes agrupar 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>
Si bien workbox-window
es bastante pequeño, podrías dividirlo de la lógica principal de la aplicación de tu sitio web con un import
dinámico, 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>
Ten en cuenta que el elemento <script>
del ejemplo anterior usa el atributo type="module"
. Esto es necesario si deseas usar instrucciones 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 se puede 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 equivale a registrar un service worker usando 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 previo en caché para evitar la contención del ancho de banda que puede retrasar el inicio de la página.
Comunicación entre el window
y el alcance del service worker
Los service workers tienen su propio alcance independiente de window
y solo tienen acceso a un subconjunto de las APIs disponibles en window
. Sin embargo, es posible la comunicación entre window
y el service worker. 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 es un objeto con las siguientes propiedades:
type
es una cadena única obligatoria que identifica el mensaje. El formato debe estar en mayúsculas con guiones bajos que separen 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 cualquier tipo de datos.
A continuación, se muestra un ejemplo de cómo funciona messageSW
, comenzando por el código de tu 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);
}
});
Luego, verás 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);
Existen muchas instancias en las que la comunicación entre un service worker y el window
puede ser útil, como notificar al usuario cuando hay una actualización de service worker disponible. Esa receta se basa en un método auxiliar especial para self.skipWaiting
llamado messageSkipWaiting
, que envía un mensaje con un valor type
de SKIP_WAITING
.