caixa de trabalho-sw

O módulo workbox-sw fornece uma maneira extremamente fácil de começar a usar os módulos do Workbox, simplifica o carregamento dos módulos do Workbox e oferece alguns métodos auxiliares simples.

É possível usar workbox-sw pela nossa CDN ou com um conjunto de arquivos de caixa de trabalho no seu próprio servidor.

Como usar o Workbox SW via CDN

A maneira mais fácil de começar a usar esse módulo é pela CDN. Basta adicionar o seguinte ao service worker:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

Com isso, você terá o namespace workbox no service worker que vai fornecer acesso a todos os módulos do Workbox.

workbox.precaching.*
workbox.routing.*
etc

Algo mágico acontece quando você começa a usar os módulos adicionais.

Quando você referencia um módulo pela primeira vez, o workbox-sw detecta isso e carrega o módulo antes de disponibilizá-lo. Confira isso acontecendo na guia "network" do DevTools.

Carregamento de bibliotecas do Workbox no DevTools

Esses arquivos serão armazenados em cache pelo navegador, disponibilizando-os para uso off-line futura.

Como usar arquivos da caixa de trabalho local em vez do CDN

Se você não quiser usar a CDN, é fácil mudar para arquivos do Workbox hospedados em seu próprio domínio.

A abordagem mais simples é receber os arquivos por meio do comando copyLibraries do workbox-cli e, em seguida, informar a workbox-sw onde encontrá-los com a opção de configuração modulePathPrefix.

Se você colocar os arquivos em /third_party/workbox-vX.Y.Z/, use-os da seguinte maneira:

importScripts('/third_party/workbox-vX.Y.Z/workbox-sw.js');

workbox.setConfig({
  modulePathPrefix: '/third_party/workbox-vX.Y.Z/',
});

Evitar importações assíncronas

Internamente, o carregamento de novos módulos pela primeira vez envolve a chamada de importScripts() com o caminho para o arquivo JavaScript correspondente (hospedado na CDN ou por um URL local). Em ambos os casos, uma restrição importante se aplica: as chamadas implícitas para importScripts() só podem acontecer dentro do gerenciador install de um service worker ou durante a execução inicial síncrona do script do service worker.

Para evitar a violação dessa restrição, uma prática recomendada é referenciar os vários namespaces workbox.* fora de quaisquer manipuladores de eventos ou funções assíncronas.

Por exemplo, o seguinte código de service worker de nível superior é adequado:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will work!
workbox.routing.registerRoute(
  ({request}) => request.destination === 'image',
  new workbox.strategies.CacheFirst()
);

Mas o código abaixo pode ser um problema se você não tiver referenciado workbox.strategies em outro lugar no service worker:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Oops! This causes workbox-strategies.js to be imported inside a fetch handler,
    // outside of the initial, synchronous service worker execution.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

Se você precisar escrever um código que poderia entrar em conflito com essa restrição, acione explicitamente a chamada importScripts() fora do manipulador de eventos usando o método workbox.loadModule():

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
workbox.loadModule('workbox-strategies');

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Referencing workbox.strategies will now work as expected.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

Como alternativa, é possível criar uma referência aos namespaces relevantes fora dos seus manipuladores de eventos e usá-la mais tarde:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
const {strategies} = workbox;

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Using the previously-initialized strategies will work as expected.
    const cacheFirst = new strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

Forçar uso de builds de depuração ou de produção

Todos os módulos do Workbox vêm com dois builds: um de depuração, que contém geração de registros e verificação de tipos adicional, e um build de produção, que elimina a geração de registros e a verificação de tipos.

Por padrão, workbox-sw usará o build de depuração para sites em localhost, mas para qualquer outra origem, usará o build de produção.

Para forçar builds de depuração ou de produção, defina a opção de configuração debug:

workbox.setConfig({
  debug: true,
});

Converter o código usando instruções de importação para usar workbox-sw

Ao carregar o Workbox usando workbox-sw, todos os pacotes desse ambiente serão acessados pelo namespace global workbox.*.

Se você tiver um exemplo de código que usa instruções import que queira converter para usar workbox-sw, basta carregar workbox-sw e substituir todas as instruções import por variáveis locais que fazem referência a esses módulos no namespace global.

Isso funciona porque todos os pacotes de service workers do Workbox publicados no npm também estão disponíveis no namespace global workbox por uma versão camelCase do nome. Por exemplo, todos os módulos exportados do pacote npm workbox-precaching podem ser encontrados em workbox.precaching.*. Além disso, todos os módulos exportados do pacote npm workbox-background-sync podem ser encontrados em workbox.backgroundSync.*).

Como exemplo, confira alguns códigos que usam instruções import referenciando módulos do Workbox:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponse} from 'workbox-cacheable-response';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);

E este é o mesmo código reescrito para usar workbox-sw. Observe que apenas as instruções de importação mudaram, a lógica não foi alterada:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

const {registerRoute} = workbox.routing;
const {CacheFirst} = workbox.strategies;
const {CacheableResponse} = workbox.cacheableResponse;

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);