Este guia se concentra nas mudanças interruptivas introduzidas na Workbox v5, com exemplos das mudanças que você precisa fazer ao fazer upgrade da Workbox v4.
Alterações importantes
Classes de plug-in renomeadas
Vários pacotes do Workbox v4 incluíam classes com o nome Plugin
. Na v5, essas classes foram renomeadas para seguir o padrão de identificador de pacote + Plugin
:
BackgroundSyncPlugin
BroadcastUpdatePlugin
CacheableResponsePlugin
ExpirationPlugin
RangeRequestsPlugin
Essa renomeação será aplicada se você estiver usando as classes por importações de módulo ou pelos namespaces workbox.*
.
Ponto de substituição do manifesto de pré-cache padrão
Anteriormente, ao usar uma das ferramentas de build em "inject manifest" , o arquivo do service worker de origem foi verificado quanto à presença de precacheAndRoute([])
, com a matriz vazia []
usada como um marcador de posição para o ponto em que o manifesto de pré-cache foi injetado.
No Workbox v5, a lógica de substituição mudou, e agora self.__WB_MANIFEST
é usado por padrão como o ponto de injeção.
// v4:
precacheAndRoute([]);
// v5:
precacheAndRoute(self.__WB_MANIFEST);
Conforme descrito nesta discussão, acreditamos que essa mudança oferece uma experiência mais simples e, ao mesmo tempo, dá aos desenvolvedores mais controle sobre como o manifesto injetado é usado no código do service worker personalizado. Se necessário, você pode mudar essa string de substituição usando a opção de configuração injectionPoint
.
Mudanças no trajeto de navegação
Duas opções que anteriormente eram compatíveis com rotas de navegação, blacklist
e whitelist
, foram renomeadas como denylist
e allowlist
.
A workbox-routing
já oferecia suporte a um método, registerNavigationRoute()
, que, por baixo dos panos, fazia duas coisas:
- Detectado se um determinado evento
fetch
teve ou nãomode
de'navigate'
. - Se sim, responda a essa solicitação usando o conteúdo de um URL fixado no código e armazenado em cache anteriormente, independentemente do URL para o qual a navegação é direcionada.
Esse é um padrão comum a ser usado ao implementar a arquitetura de shell do app.
A segunda etapa, gerar uma resposta lendo do cache, não está dentro das responsabilidades do workbox-routing
. Em vez disso, consideramos que ela faz parte da workbox-precaching
, usando um novo método, createHandlerBoundToURL()
. Esse novo método pode trabalhar em conjunto com a classe NavigationRoute
já existente no workbox-routing
para realizar a mesma lógica.
Se você estiver usando a opção navigateFallback
em um dos comandos "generate SW" da ferramenta de build, a mudança acontecerá automaticamente. Se você já tiver configurado as opções navigateFallbackBlacklist
ou navigateFallbackWhitelist
, mude para navigateFallbackDenylist
ou navigateFallbackAllowlist
, respectivamente.
Se você usa "inject manifest" ou apenas gravar o service worker e seu service worker da Workbox v4 chamar registerNavigationRoute()
diretamente, será necessário fazer uma mudança no código para ter o comportamento equivalente.
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
Não é mais necessário chamar getCacheKeyForURL()
, porque createHandlerBoundToURL()
cuidará disso para você.
Remoção de makeRequest() de workbox-strategies
Chamar makeRequest()
equivale a chamar handle()
em uma das classes workbox-strategy
. As diferenças entre os dois métodos eram tão pequenas que manter os dois não fazia sentido. Os desenvolvedores que chamaram makeRequest()
vão poder passar a usar handle()
sem fazer mais mudanças:
// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});
// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});
Na v5, handle()
trata request
como um parâmetro obrigatório e não voltará a usar event.request
. Transmita uma solicitação válida ao chamar handle()
.
workbox-broadcast-update sempre usa postMessage()
Na v4, a biblioteca workbox-broadcast-update
usaria, por padrão, a API Broadcast Channel para enviar mensagens quando há suporte a ela e volta a usar postMessage()
somente quando o canal de transmissão não é compatível.
Percebemos que ter que detectar duas possíveis fontes de mensagens recebidas tornou a escrita do código no lado do cliente muito complicada. Além disso, em alguns navegadores, as chamadas postMessage()
do service worker enviadas para páginas clientes são automaticamente armazenadas em buffer até que um listener de eventos message
seja configurado. Não há buffer com a API Broadcast Channel, e as mensagens transmitidas são descartadas se forem enviadas antes que uma página do cliente esteja pronta para recebê-las.
Por esses motivos, mudamos a workbox-broadcast-update
para usar sempre a postMessage()
na v5. As mensagens são enviadas uma por vez para todas as páginas do cliente no escopo do service worker atual.
Para acomodar esse novo comportamento, remova qualquer código que você tenha em páginas de cliente que criaram instâncias de BroadcastChannel
e configure um listener de evento message
em navigator.serviceWorker
:
// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
});
// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
}
});
Os usuários do workbox-window
não precisam fazer nenhuma mudança, porque a lógica interna foi atualizada para detectar chamadas postMessage()
.
As ferramentas de build exigem o Node.js v8 ou mais recente
As versões do Node.js anteriores à v8 não são mais compatíveis com workbox-webpack-plugin
, workbox-build
ou workbox-cli
. Se você estiver executando uma versão do Node.js anterior à 8, atualize o ambiente de execução para uma versão compatível.
workbox-webpack-plugin Requer o webpack v4 ou mais recente
Se você estiver usando workbox-webpack-plugin
, atualize a configuração do webpack para usar pelo menos o webpack v4.
Reestruturação da opção de ferramenta de build
Vários parâmetros de configuração workbox-build
, workbox-cli
e workbox-webpack-plugin
não têm mais suporte. Por exemplo, generateSW
sempre vai criar um pacote de ambiente de execução do Workbox local para você, então a opção importWorkboxFrom
não faz mais sentido.
Consulte a documentação da ferramenta relevante para ver as listas de opções compatíveis.
Remoção de generateSWString do build da caixa de trabalho.
O modo generateSWString
foi removido do workbox-build
. Esperamos que esse impacto seja mínimo, já que foi usado internamente pelo workbox-webpack-plugin
.
Alterações opcionais
Como usar importações de módulo
Embora essa mudança seja a) opcional e b) tecnicamente possível com o uso do Workbox v4, a maior mudança prevista para a v5 é um modelo em que você cria seu próprio service worker em pacote importando os módulos do Workbox. Essa abordagem é uma alternativa a chamar importScripts('/path/to/workbox-sw.js')
na parte superior do service worker e usar o Workbox pelo namespace workbox.*
.
Se você estiver usando uma das ferramentas de build (workbox-webpack-plugin
, workbox-build
, workbox-cli
) no modo "gerar SW", essa mudança vai acontecer automaticamente. Todas essas ferramentas vão gerar um pacote local e personalizado do Workbox runtime com o código necessário para implementar a lógica do service worker. Nesse cenário, não há mais dependência do workbox-sw
ou da cópia CDN do Workbox. Dependendo do valor da configuração do inlineWorkboxRuntime
, o ambiente de execução do Workbox será dividido em um arquivo separado, que será implantado com o service worker (quando definido como false
, que é o padrão) ou incluído inline com a lógica do service worker (quando definido como true
).
Se você estiver usando as ferramentas de build no modo "inject manifest" ou não estiver usando as ferramentas de build do Workbox, saiba mais sobre como criar seu próprio pacote de execução do Workbox no guia Como usar os bundlers (webpack/Rollup) com o Workbox.
A documentação e os exemplos da v5 foram escritos com base na sintaxe de importação de módulos, mas o namespace workbox.*
vai continuar sendo compatível com a Workbox v5.
Como ler respostas pré-armazenadas em cache
Alguns desenvolvedores precisam ler as respostas pré-armazenadas em cache diretamente do cache, em vez de usá-las implicitamente com o método precacheAndRoute()
. Um padrão comum na v4 é primeiro receber a chave de cache específica da versão atual de um recurso pré-armazenado em cache e, em seguida, transmitir essa chave com o nome do cache da pré-armazenagem para caches.match()
para receber o Response
.
Para simplificar esse processo, workbox-precaching
na v5 é compatível com um novo método equivalente, matchPrecache()
:
// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';
const cachedResponse = await caches.match(
getCacheKeyForURL(`/somethingPrecached`),
{
cacheName: cacheNames.precache,
}
);
// v5:
import {matchPrecache} from 'workbox-precaching';
const cachedResponse = await matchPrecache(`/somethingPrecached`);
Adoção do TypeScript
Na v5, as bibliotecas de tempo de execução do Workbox são escritas em TypeScript. Continuaremos a publicar módulos e pacotes JavaScript transcompilados para acomodar desenvolvedores que não adotaram o TypeScript, mas se você estiver usando o TypeScript, poderá se beneficiar de informações precisas e sempre atualizadas diretamente do projeto Workbox.
Exemplo de migração
Este commit ilustra uma migração bastante complexa, com comentários inline. Ele usa o Rollup para incluir um ambiente de execução do Workbox personalizado no worker de serviço final em vez de carregar o ambiente de execução do CDN.
Embora não cubra todas as alterações interruptivas, veja o antes e o depois do upgrade de um arquivo de service worker da v4 para a v5, incluindo a mudança para o TypeScript.
Como receber ajuda
A maioria das migrações é simples. Se você encontrar problemas não abordados neste guia, abra um problema no GitHub.