Um módulo do Workbox que ainda não foi muito abordado nesta documentação é o workbox-window
, que é um conjunto de módulos destinados a ser executado no window
. Os objetivos deste módulo são:
- Simplificar o registro e as atualizações de service workers ajudando os desenvolvedores a identificar momentos críticos do ciclo de vida de service workers, facilitando a resposta a esses momentos.
- Para evitar que os desenvolvedores cometam erros comuns, como registrar um worker de serviço no escopo errado.
- Para simplificar a mensagem entre o
window
e o escopo do service worker.
Importar e usar workbox-window
A exportação que você vai usar com mais frequência do workbox-window
é a classe Workbox
, que pode ser importada no nó ou do CDN em uma página da Web.
Como criar um pacote local
Se a cadeia de ferramentas incluir um bundler como webpack ou Rollup, será possível agrupar workbox-window
localmente.
Primeiro, instale workbox-window
como uma dependência de produção do seu aplicativo:
npm install workbox-window --save
Em seguida, no JavaScript do aplicativo, você pode import
a classe Workbox
de workbox-window
:
<script type="module">
import {Workbox} from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Embora workbox-window
seja bastante pequeno, você pode dividi-lo da lógica de aplicativo principal do seu site usando import
dinâmico, o que pode reduzir o tamanho do pacote principal da página:
<script type="module">
if ('serviceWorker' in navigator) {
const {Workbox} = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Como usar a CDN
Embora não seja a abordagem recomendada, uma maneira mais fácil de usar o workbox-window
é importá-lo de uma 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>
O elemento <script>
no exemplo acima usa o atributo type="module"
. Isso é necessário se você quer usar instruções import
estáticas no navegador sem uma etapa de build. Todos os principais navegadores compatíveis com service workers também são compatíveis com módulos JavaScript, então não há problema em disponibilizar esse código em qualquer navegador, já que navegadores mais antigos ignorarão elementos <script>
com um valor de atributo type
de "module"
.
Como registrar um service worker
O registro de um service worker com workbox-window
é feito com o método register
da classe Workbox
, desta forma:
import {Workbox} from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
Pode parecer que isso é o mesmo que registrar um service worker usando navigator.serviceWorker.register
. No entanto, Workbox.register
aguarda até o evento window
load
antes de registrar o worker de serviço. Isso é desejável em situações em que o pré-armazenamento em cache está envolvido, para evitar a contenção de largura de banda que pode atrasar a inicialização da página.
Como estabelecer comunicação entre o window
e o escopo do service worker
Os service workers têm um escopo separado do window
e têm acesso apenas a um subconjunto das APIs disponíveis no window
. No entanto, é possível estabelecer comunicação entre a window
e o service worker. workbox-window
facilita a comunicação entre os dois escopos com o método messageSW
do módulo workbox-window
.
O Workbox usa um formato específico para mensagens, que é um objeto com as seguintes propriedades:
type
é uma string exclusiva obrigatória que identifica a mensagem. O formato precisa ser em letras maiúsculas com sublinhados separando as palavras (por exemplo,CACHE_URLS
).meta
é uma string opcional que representa o nome do pacote do Workbox que está enviando a mensagem e geralmente é omitida.payload
é um parâmetro opcional que representa os dados que você quer enviar. Pode ser qualquer tipo de dados.
Veja abaixo um exemplo de como messageSW
funciona, começando com o código no seu 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);
}
});
Depois, use o seguinte código na sua página da Web:
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
Há muitos casos em que a comunicação entre um service worker e o window
pode ser útil, como notificar o usuário quando uma atualização do service worker está disponível. Essa receita depende de um método auxiliar especial para self.skipWaiting
chamado messageSkipWaiting
, que envia uma mensagem com um valor type
de SKIP_WAITING
.