Migrar do Workbox v5 para v6

Este guia se concentra em alterações interruptivas introduzidas no Workbox v6, com exemplos das mudanças que você precisaria fazer ao fazer upgrade do Workbox v5.

Alterações importantes

núcleo da caixa de trabalho

O método skipWaiting() em workbox-core não adicionará mais um gerenciador install e é equivalente a apenas chamar self.skipWaiting().

A partir de agora, use self.skipWaiting(), porque o skipWaiting() provavelmente será removido no Workbox v7.

pré-armazenamento em cache na caixa de trabalho

  • Os documentos HTML de origem cruzada para URLs que correspondem a um redirecionamento HTTP não podem mais ser usados para atender a uma solicitação de navegação com workbox-precaching. Esse cenário geralmente não é comum.
  • O parâmetro de consulta do URL fbclid agora é ignorado por workbox-precaching ao procurar uma resposta pré-armazenada em cache para uma determinada solicitação.
  • O construtor PrecacheController agora aceita um objeto com propriedades específicas como parâmetro, em vez de uma string. Esse objeto é compatível com as seguintes propriedades: cacheName (com a mesma finalidade da string transmitida ao construtor na v5), plugins (substituindo o método addPlugins() da v5) e fallbackToNetwork (substituindo a opção semelhante transmitida para createHandler() e "createHandlerBoundToURL() na v5).
  • Os métodos install() e activate() de PrecacheController agora usam exatamente um parâmetro, que precisa ser definido como um InstallEvent ou ActivateEvent correspondentes, respectivamente.
  • O método addRoute() foi removido de PrecacheController. No lugar dela, a nova classe PrecacheRoute pode ser usada para criar uma rota que você pode registrar.
  • O método precacheAndRoute() foi removido de PrecacheController. Ele ainda existe como um método auxiliar estático exportado pelo módulo workbox-precaching. Ela foi removida porque PrecacheRoute pode ser usada.
  • O método createMatchCalback() foi removido de PrecacheController. O novo PrecacheRoute pode ser usado.
  • O método createHandler() foi removido de PrecacheController. A propriedade strategy do objeto PrecacheController pode ser usada para processar solicitações.
  • A exportação estática createHandler() já foi removida do módulo workbox-precaching. No lugar dele, os desenvolvedores precisam criar uma instância de PrecacheController e usar a propriedade strategy.
  • A rota registrada com precacheAndRoute() agora é uma rota "real" que usa a classe Router do workbox-routing em segundo plano. Isso pode levar a uma ordem de avaliação diferente das suas rotas se você intercalar as chamadas para registerRoute() e precacheAndRoute().

roteamento de caixa de trabalho

O método setDefaultHandler() agora usa um segundo parâmetro opcional correspondente ao método HTTP a que ele se aplica. O padrão é 'GET'.

  • Se você usa setDefaultHandler() e todas as suas solicitações são GET, nenhuma mudança precisa ser feita.
  • Se você tiver alguma solicitação que não seja GET (POST, PUT etc.), setDefaultHandler() não vai mais corresponder a essas solicitações.

Configuração do Cloud Build

A opção mode para os modos getManifest e injectManifest em workbox-build e workbox-cli não deveria ser compatível e foi removida. Isso não se aplica a workbox-webpack-plugin, que é compatível com mode no plug-in InjectManifest.

As ferramentas de build exigem o Node.js v10 ou mais recente

As versões do Node.js anteriores à v10 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 à v8, atualize o ambiente de execução para uma versão compatível.

Novas melhorias

estratégias de caixa de trabalho

O Workbox v6 apresenta uma nova maneira para desenvolvedores terceirizados definirem as próprias estratégias do Workbox. Isso garante que desenvolvedores terceirizados possam ampliar o Workbox para atender totalmente às necessidades deles.

Nova classe base de estratégia

Na v6, todas as classes de estratégia da caixa de trabalho precisam estender a nova classe de base Strategy. Todas as estratégias integradas foram reescritas para dar suporte a isso.

A classe de base Strategy é responsável por dois itens principais:

  • Invocar callbacks do ciclo de vida do plug-in comuns a todos os gerenciadores de estratégia (por exemplo, quando eles iniciam, respondem e terminam).
  • Criar uma instância "gerenciador", que possa gerenciar o estado de cada solicitação individual que uma estratégia está tratando.

Nova classe "handler"

Anteriormente, módulos internos chamam fetchWrapper e cacheWrapper, que (como o nome indica) unem as várias APIs de busca e cache com hooks no ciclo de vida. Atualmente, esse é o mecanismo que permite que os plug-ins funcionem, mas não é exposto aos desenvolvedores.

A nova classe "handler", StrategyHandler, vai expor esses métodos para que as estratégias personalizadas possam chamar fetch() ou cacheMatch() e fazer com que todos os plug-ins adicionados à instância da estratégia sejam invocados automaticamente.

Essa classe também possibilita que os desenvolvedores adicionem seus próprios callbacks personalizados do ciclo de vida que podem ser específicos às estratégias deles, e eles "simplesmente funcionam" com a interface do plug-in existente.

Novo estado do ciclo de vida do plug-in

No Workbox v5, os plug-ins não têm estado. Isso significa que, se uma solicitação de /index.html acionar os callbacks requestWillFetch e cachedResponseWillBeUsed, eles não terão como se comunicar entre si ou mesmo saber que foram acionados pela mesma solicitação.

Na v6, todos os callbacks de plug-ins também receberão um novo objeto state. Esse objeto de estado será exclusivo para este objeto de plug-in específico e para esta invocação de estratégia específica (ou seja, a chamada para handle()). Isso permite que os desenvolvedores escrevam plug-ins em que um callback pode fazer algo condicionalmente com base no que outro callback no mesmo plug-in fez (por exemplo, calcular o delta de tempo entre executar requestWillFetch e fetchDidSucceed ou fetchDidFail).

Novos callbacks do ciclo de vida do plug-in

Novos callbacks do ciclo de vida do plug-in foram adicionados para permitir que os desenvolvedores aproveitem totalmente o estado do ciclo de vida do plug-in:

  • handlerWillStart: chamado antes de qualquer lógica de gerenciador começar a ser executada. Esse callback pode ser usado para definir o estado inicial do gerenciador (por exemplo, registrar o horário de início).
  • handlerWillRespond: chamado antes do método handle() das estratégias retornar uma resposta. Esse callback pode ser usado para modificar essa resposta antes de retorná-la a um gerenciador de rotas ou outra lógica personalizada.
  • handlerDidRespond: chamado depois que o método handle() da estratégia retorna uma resposta. Esse retorno de chamada pode ser usado para registrar quaisquer detalhes finais da resposta, por exemplo, após alterações feitas por outros plug-ins.
  • handlerDidComplete: chamado depois que todas as promessas de extensão de ciclo de vida adicionadas ao evento da invocação dessa estratégia tiverem sido resolvidas. Esse retorno de chamada pode ser usado para relatar quaisquer dados que precisem aguardar até que o gerenciador seja concluído para fazer cálculos (por exemplo, status de ocorrência em cache, latência do cache, latência da rede).
  • handlerDidError: chamado se o gerenciador não consegue fornecer uma resposta válida de qualquer origem. Esse callback pode ser usado para fornecer conteúdo "substituto" como alternativa a um erro de rede.

Os desenvolvedores que implementam as próprias estratégias personalizadas não precisam se preocupar em invocar esses callbacks. Tudo isso é processado por uma nova classe de base Strategy.

Tipos de TypeScript mais precisos para gerenciadores

As definições do TypeScript para vários métodos de callback foram normalizadas. Isso proporciona uma experiência melhor para os desenvolvedores que usam o TypeScript e escrevem o próprio código para implementar ou chamar gerenciadores.

janela de caixa de trabalho

Novo método messageSkipEspereing()

Um novo método, messageSkipWaiting(), foi adicionado ao módulo workbox-window para simplificar o processo de ativação do service worker"waiting". Isso oferece algumas melhorias:

  • Ele chama postMessage() com o corpo da mensagem padrão, {type: 'SKIP_WAITING'}, que um service worker gerado pelo Workbox verifica para acionar skipWaiting().
  • Ele escolhe o service worker "aguardando" correto para postar essa mensagem, mesmo que não seja o mesmo service worker em que o workbox-window foi registrado.

Remoção de eventos "externos" em favor de uma propriedade isExternal.

Todos os eventos "external" em workbox-window foram removidos no lugar dos eventos "normais" com uma propriedade isExternal definida como true. Assim, os desenvolvedores que se preocupam com a distinção podem detectá-la, e aqueles que não precisam saber podem ignorar a propriedade.

Receita de limpeza "Oferecer uma atualização de página para os usuários"

Graças a ambas as alterações acima, é possível simplificar o roteiro "Oferecer uma atualização da página para os usuários":

MULTI_LINE_CODE_PLACEHOLDER_0

roteamento de caixa de trabalho

Um novo parâmetro booleano, sameOrigin, é transmitido para a função matchCallback usada em workbox-routing. Ele é definido como true se a solicitação for para um URL de mesma origem. Caso contrário, é definido como "false".

Isso simplifica alguns códigos boilerplate comuns:

MULTI_LINE_CODE_PLACEHOLDER_1

matchOptions em workbox-expiration

Agora você pode definir matchOptions em workbox-expiration, que vai ser transmitido como CacheQueryOptions para a chamada cache.delete(). A maioria dos desenvolvedores não precisará fazer isso.

pré-armazenamento em cache na caixa de trabalho

Usa estratégias de caixa de trabalho

O workbox-precaching foi reescrito para usar workbox-strategies como base. Isso não deve resultar em alterações interruptivas e deve levar a uma melhor consistência a longo prazo na forma como os dois módulos acessam a rede e o cache.

O pré-armazenamento em cache agora processa as entradas uma a uma, não em massa.

O workbox-precaching foi atualizado para que apenas uma entrada no manifesto de pré-cache seja solicitada e armazenada em cache por vez, em vez de tentar solicitar e armazenar todas as entradas em cache de uma só vez (deixando para o navegador descobrir como limitar esse processo).

Isso deve reduzir a probabilidade de erros net::ERR_INSUFFICIENT_RESOURCES durante o pré-armazenamento em cache, além de reduzir a contenção de largura de banda entre pré-armazenamento em cache e solicitações simultâneas feitas pelo app da Web.

O PrecacheFallbackPlugin possibilita a substituição off-line mais fácil

workbox-precaching agora inclui um PrecacheFallbackPlugin, que implementa o novo método de ciclo de vida handlerDidError adicionado na v6.

Isso facilita a especificação de um URL armazenado em cache como "substituto" para uma determinada estratégia quando uma resposta não estaria disponível. O plug-in será responsável pela construção adequada da chave de cache correta para o URL pré-armazenado, incluindo qualquer parâmetro de revisão necessário.

Confira um exemplo de como usá-lo para responder com um /offline.html pré-armazenado em cache quando a estratégia NetworkOnly não consegue gerar uma resposta para uma solicitação de navegação. Em outras palavras, ela mostra uma página HTML off-line personalizada:

MULTI_LINE_CODE_PLACEHOLDER_2

precacheFallback em cache no momento da execução

Se você estiver usando generateSW para criar um service worker em vez de escrever o service worker manualmente, poderá usar a nova opção de configuração precacheFallback no runtimeCaching para fazer o mesmo:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

Como buscar ajuda

Acreditamos que a maioria das migrações será simples. Se você tiver problemas que não foram abordados neste guia, abra um problema (link em inglês) no GitHub.