Migrar do Workbox v2 para a v3

O foco deste guia são as alterações interruptivas introduzidas no Workbox v3, com exemplos das mudanças que você precisa fazer ao fazer upgrade de uma configuração do Workbox v2.

Se você estiver usando a combinação legada sw-precache/sw-toolbox e quiser fazer a transição para o Workbox pela primeira vez, este guia de migração vai ajudar.

Plano de fundo da v3

A versão v3 do Workbox representa uma refatoração significativa da base de código existente. As metas gerais são:

  • Minimize o tamanho da caixa de trabalho. A quantidade de códigos do ambiente de execução do service worker que é transferida por download e executado foi reduzida. Em vez de permitir que todos participem de um pacote monolítico, somente o código para os recursos específicos que você está usando será importado no ambiente de execução.
  • O Workbox tem uma CDN. Oferecemos uma hospedagem de CDN totalmente compatível e baseada no Google Cloud Storage como opção canônica para acessar as bibliotecas de ambiente de execução do Workbox, facilitando a instalação e a execução dele.
  • Melhor depuração e registros. A experiência de depuração e geração de registros foi bastante aprimorada. Os registros de depuração são ativados por padrão sempre que o Workbox é usado de uma origem localhost e todos os registros e declarações são removidos dos builds de produção. Exemplo de geração de registros de depuração oferecido pelo Workbox v3.
  • Plug-in webpack aprimorado. O workbox-webpack-plugin se integra melhor ao processo de build do webpack, permitindo um caso de uso sem configuração quando você quer pré-armazenar em cache todos os recursos no pipeline de build.

Alcançar essas metas e limpar alguns aspectos da interface anterior que pareciam estranhos ou geravam antipadrões exigiu a introdução de uma série de alterações interruptivas na versão v3.

Alterações importantes

Configuração do Cloud Build

As mudanças abaixo afetam o comportamento de todas as nossas ferramentas de build (workbox-build, workbox-cli, workbox-webpack-plugin), que compartilham o mesmo conjunto de opções de configuração.

  • O nome do gerenciador 'fastest' era válido e tratado como um alias para 'staleWhileRevalidate' ao configurar runtimeCaching. Ele não é mais válido, e os desenvolvedores precisam passar a usar 'staleWhileRevalidate' diretamente.
  • Vários nomes de propriedades runtimeCaching.options foram atualizados e há uma validação de parâmetro adicional em vigor, que vai causar a falha do build se uma configuração inválida for usada. Consulte a documentação de runtimeCaching para ver uma lista das opções compatíveis no momento.

workbox-background-sync

  • O parâmetro de configuração maxRetentionTime agora é interpretado como um número de minutos, em vez de um número de milissegundos.
  • Agora há uma string obrigatória, representando o nome da fila, que deve ser passado como o primeiro parâmetro ao construir o plug-in ou a classe autônoma. Ele foi transmitido anteriormente como uma propriedade das opções. Consulte a documentação da plataforma atualizada da API.

workbox-broadcast-cache-update

  • Agora há uma string obrigatória, que representa o nome do canal, que precisa ser transmitida como o primeiro parâmetro ao construir o plug-in ou a classe autônoma.

Por exemplo, na v2, você inicializaria a classe Plugin da seguinte maneira:

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

O uso equivalente na v3 é:

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

Consulte a documentação da plataforma atualizada da API.

workbox-build

  • Por padrão, a correspondência de padrões glob agora é realizada com as opções follow: true (que virão depois dos links simbólicos) e strict: true (que é menos tolerante a erros "incomuns"). É possível desativar ambos e retornar ao comportamento anterior definindo globFollow: false e/ou globStrict: false na configuração do build.
  • Todas as funções em workbox-build retornam uma propriedade extra, warnings, nas respostas retornadas. Alguns cenários que eram tratados como erros fatais na v2 agora são permitidos, mas informados por warnings, que é uma matriz de strings.

Na v2, você pode chamar generateSW da seguinte maneira:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

Embora você possa usar o mesmo código na v3, é recomendável verificar se há warnings e registrá-los:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • Os desenvolvedores que criaram as próprias funções ManifestTransform personalizadas na v2 precisam retornar a matriz do manifesto em um objeto. Ou seja, em vez de return manifestArray;, use return {manifest: manifestArray};.mIsso permite que seu plug-in inclua uma propriedade warnings opcional, que precisa ser uma matriz de strings contendo informações de aviso não fatais.

Se você estivesse criando um ManifestTransform personalizado na v2, o código seria assim:

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

tem um equivalente na v3 de:

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};
  • A função getFileManifestEntries() foi renomeada como getManifest(), e a promessa retornada agora inclui informações adicionais sobre os URLs que estão pré-armazenados em cache.

Insira o código abaixo na v2:

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

pode ser reescrito na v3 como:

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • A função generateFileManifest() foi removida. Incentivamos os desenvolvedores a chamar getManifest() e usar a resposta dele para gravar dados no disco no formato apropriado.

workbox-cache-expiration

  • A API do plug-in permanece a mesma, que é o modo que a maioria dos desenvolvedores acabará usando. No entanto, há mudanças significativas na API que afetam os desenvolvedores que a usam como uma classe independente. Consulte a documentação da plataforma atualizada da API.

workbox-cli

Os desenvolvedores podem executar a CLI com a flag --help para um conjunto completo de parâmetros com suporte.

  • O suporte para o alias workbox-cli do script binário foi removido. O binário agora só pode ser acessado como workbox.
  • Os comandos v2 generate:sw e inject:manifest foram renomeados como generateSW e injectManifest na v3.
  • Na v2, o arquivo de configuração padrão (usado quando um não foi explicitamente fornecido) foi considerado workbox-cli-config.js no diretório atual. Na v3, é workbox-config.js.

Em conjunto, isso significa que na v2:

$ workbox inject:manifest

executaria o processo de compilação "inject manifest", usando uma configuração lida de workbox-cli-config.js e na v3:

$ workbox injectManifest

fará o mesmo, mas lê a configuração de workbox-config.js.

pré-armazenamento em cache da caixa de trabalho

  • Anteriormente, o método precache() realizava as modificações de cache e configurou o roteamento para exibir entradas em cache. Agora, precache() modifica apenas entradas de cache, e um novo método, addRoute(), foi exposto para registrar uma rota para disponibilizar essas respostas armazenadas em cache. Os desenvolvedores que quiserem usar a funcionalidade dois em um anterior poderão começar a chamar precacheAndRoute().
  • Várias opções que eram configuradas pelo construtor WorkboxSW agora são transmitidas como o parâmetro options em workbox.precaching.precacheAndRoute([...], options) Os padrões dessas opções, quando não configurados, são listados nos documentos de referência.
  • Por padrão, os URLs sem extensão de arquivo são automaticamente verificados em busca de uma correspondência com uma entrada de cache que contém uma extensão .html. Por exemplo, se uma solicitação for feita para /path/to/index (que não é pré-armazenada em cache) e houver uma entrada pré-armazenada em cache para /path/to/index.html, essa entrada vai ser usada. Os desenvolvedores podem desativar esse novo comportamento definindo {cleanUrls: false} ao transmitir opções para workbox.precaching.precacheAndRoute()
  • O workbox-broadcast-update não será mais configurado automaticamente para anunciar atualizações de cache para recursos pré-armazenados em cache.

O código a seguir na v2:

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

tem um equivalente na v3 de:

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

roteamento da caixa de trabalho

  • Os desenvolvedores que já usavam o workbox-routing com o namespace workbox.router.* de um objeto WorkboxSW precisam mudar para o novo namespace, workbox.routing.*.
  • Agora os trajetos são avaliados em uma ordem "first-registered-wins". Esta é a ordem oposta de avaliação Route que foi usada na v2, em que o último Route registrado teria precedência.
  • A classe ExpressRoute e o suporte para caracteres curinga "estilo Express" foram removidos. Isso reduz consideravelmente o tamanho de workbox-routing. As strings usadas como o primeiro parâmetro para workbox.routing.registerRoute() agora vão ser tratadas como correspondências exatas. Correspondências curinga ou parciais precisam ser tratadas por RegExps. Usar qualquer RegExp que corresponda a parte ou a todo o URL da solicitação pode acionar uma rota.
  • O método auxiliar addFetchListener() da classe Router foi removido. Os desenvolvedores podem adicionar o próprio gerenciador fetch explicitamente ou usar a interface fornecida por workbox.routing, que cria implicitamente um gerenciador fetch para eles.
  • Os métodos registerRoutes() e unregisterRoutes() foram removidos. As versões desses métodos que operam em uma única Route não foram modificadas, e os desenvolvedores que precisam registrar ou cancelar o registro de várias rotas de uma vez precisam fazer uma série de chamadas para registerRoute() ou unregisterRoute().

O código a seguir na v2:

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

tem um equivalente na v3 de:

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

estratégias de caixa de trabalho (anteriormente conhecidas como workbox-runtime-armazenamento em cache)

  • O módulo workbox-runtime-caching agora é oficialmente conhecido como workbox-strategies e foi publicado no npm com o novo nome.
  • Não é mais válido usar a expiração do cache em uma estratégia sem fornecer um nome de cache. Na v2, isso era possível:
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

Isso levaria a entradas expiradas no cache padrão, o que é inesperado. Na v3, um nome de cache é obrigatório:

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • O método cacheWillMatch do ciclo de vida foi renomeado como cachedResponseWillBeUsed Essa mudança não será visível para os desenvolvedores, a menos que eles tenham criado os próprios plug-ins com reações ao cacheWillMatch.
  • A sintaxe para especificar plug-ins ao configurar uma estratégia foi alterada. Cada plug-in precisa estar explicitamente listado na propriedade plugins da configuração da estratégia.

O código a seguir na v2:

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

tem um equivalente na v3 de:

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

Saiba mais no guia Como usar plug-ins.

workbox-sw

  • Internamente, o workbox-sw foi reescrito para ser uma interface de "carregador" leve, que requer uma configuração básica e é responsável por extrair os outros módulos necessários no momento da execução. Em vez de criar uma nova instância da classe WorkboxSW, os desenvolvedores interagem com uma instância existente que é exposta automaticamente no namespace global.

Anteriormente na v2:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

Na v3, você só precisa importar o script workbox-sw.js, e uma instância pronta para uso vai estar disponível automaticamente no namespace global como workbox:

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • skipWaiting e clientsClaim não são mais opções transmitidas para o construtor WorkboxSW. Em vez disso, eles foram alterados para os métodos workbox.clientsClaim() e workbox.skipWaiting().
  • A opção handleFetch, que anteriormente era compatível com o construtor v2, não tem mais suporte na v3. Os desenvolvedores que precisam de recursos semelhantes para testar o service worker sem que nenhum gerenciador de busca seja invocado podem usar a opção "Ignorar para a rede", disponível nas Ferramentas para desenvolvedores do Chrome.
A opção &quot;Ignorar para rede&quot; no Chrome DevTools.

plug-in-de-pacote-de-trabalho

O plug-in foi reescrito e, em muitos casos, pode ser usado no modo de "configuração zero". Consulte a documentação da plataforma atualizada da API.

  • A API agora expõe duas classes, GenerateSW e InjectManifest. Isso torna a alternância entre os modos explícita, em comparação com o comportamento da v2, em que o comportamento mudou com base na presença de swSrc
  • Por padrão, os recursos no pipeline de compilação do webpack são pré-armazenados em cache e não é mais necessário configurar globPatterns. O único motivo para continuar usando globPatterns é se você precisar armazenar em cache recursos não incluídos no build do webpack. Em geral, ao migrar para o plug-in v3, é preciso começar removendo toda a configuração anterior baseada em glob e só adicionar de novo se você precisar.

Receber ajuda

Acreditamos que a maioria das migrações são simples. Se você tiver problemas não abordados neste guia, abra um problema no GitHub para nos informar.