Usa Workbox sin almacenamiento previo en caché

Hasta ahora, esta documentación se ha centrado en el almacenamiento previo en caché, a menudo en las herramientas de compilación generateSW y injectManifest. Si bien existen muchas buenas razones para incluir lógica de almacenamiento previo en caché en tu service worker, no necesitas usar este tipo de almacenamiento para usar Workbox.

Tal vez tu proyecto solo necesita almacenamiento en caché en el tiempo de ejecución o quizás desees una forma más limpia de integrar las APIs de service worker, como el web push. Estos son casos en los que no querrás usar las herramientas de compilación de Workbox, y eso es lo que se aborda en este artículo.

Cuando uses un agrupador

Los agrupadores son prominentes en el panorama del desarrollo web, y es muy probable que tu proyecto use uno de ellos. Si este es el caso, es importante que sepas que no necesitas usar un complemento de agrupador (como workbox-webpack-plugin) si no almacenas en caché nada. En tu aplicación, tratarás al service worker como un punto de entrada independiente.

En la raíz del directorio del código fuente de tu proyecto, crearás un service worker y usarás los módulos de Workbox que requiera tu aplicación. A continuación, se muestra un ejemplo sin almacenamiento en caché en el que se configuran estrategias de almacenamiento en caché para la navegación y las solicitudes de recursos de imagen en instancias Cache separadas:

// sw.js
import {NetworkFirst, CacheFirst} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';

const navigationRoute = new NavigationRoute(new NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new Route(({request}) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'image-assets'
}));

registerRoute(navigationRoute);
registerRoute(imageAssetRoute);

A partir de aquí, solo se debe especificar este service worker como punto de entrada en el agrupador que elijas. A continuación, se presentan algunos ejemplos de cómo hacerlo con algunos agrupadores populares.

webpack

webpack acepta puntos de entrada en su configuración de entry. Debes tener en cuenta algunos aspectos cuando uses este enfoque:

  1. Para garantizar que el service worker tenga el alcance más amplio posible, te recomendamos que se envíe a la raíz del directorio de salida.
  2. No es recomendable que se controlen las versiones del service worker, ya que las actualizaciones generarán hashes nuevos que pueden provocar la implementación de varios service workers en tu sitio web.

Para satisfacer las condiciones anteriores, se puede pasar una función a output.filename, que examina si el punto de entrada actual que se procesa es el del service worker. De lo contrario, los archivos con versión se escriben en sus destinos normales.

// webpack.config.js
import process from 'process';

const isProd = process.env.NODE_ENV === 'production';

export default {
  mode: isProd ? 'production' : 'development',
  context: process.cwd(),
  entry: {
    // Service worker entry point:
    sw: './src/sw.js',
    // Application entry point:
    app: './src/index.js'
  },
  output: {
    filename: ({runtime}) => {
      // Check if the current filename is for the service worker:
      if (runtime === 'sw') {
        // Output a service worker in the root of the dist directory
        // Also, ensure the output file name doesn't have a hash in it
        return '[name].js';
      }

      // Otherwise, output files as normal
      return 'js/[name].[contenthash:8].js';
    },
    path: './dist',
    publicPath: '/',
    clean: true
  }
};

resumen

Rollup es una situación similar a webpack, excepto que se especifican varios puntos de entrada como objetos de configuración independientes exportados en un array:

// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';

// Plugins common to both entry points
const plugins = [
  nodeResolve(),
];

export default [
  // Application entry point
  {
    input: './src/index.js',
    output: {
      dir: './dist/js',
      format: 'esm'
    },
    plugins
  },
  // Service worker entry point
  {
    input: './src/sw.js',
    output: {
      file: './dist/sw.js',
      format: 'iife'
    },
    plugins: [
      ...plugins,
      // This @rollup/plugin-replace instance replaces process.env.NODE_ENV
      // statements in the Workbox libraries to match your current environment.
      // This changes whether logging is enabled ('development') or disabled ('production').
      replace({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
      })
    ]
  }
];

compilación

esbuild ofrece una interfaz de línea de comandos sencilla:

npx esbuild ./src/sw.js --bundle --minify --outfile=./dist/sw.js

esbuild se encargará de reemplazar process.env.NODE_ENV por “development” de forma predeterminada o “production” si está habilitada la reducción.

Sin un agrupador que use workbox-sw

Es posible que tu proyecto ni siquiera use un agrupador. workbox-sw puede cargar el entorno de ejecución de Workbox por ti desde una CDN dentro del service worker y sin un paso de compilación si lo importas con importScripts:

// sw.js

// Imports Workbox from the CDN. Note that "6.2.0" of the URL
// is the version of the Workbox runtime.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-sw.js');

const navigationRoute = new workbox.routing.NavigationRoute(new workbox.strategies.NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new workbox.routing.Route(({request}) => {
  return request.destination === 'image';
}, new workbox.strategies.CacheFirst({
  cacheName: 'image-assets'
}));

workbox.routing.registerRoute(navigationRoute);
workbox.routing.registerRoute(staticAssetRoute);

Si la posibilidad de cargar el entorno de ejecución de Workbox desde una CDN no parece buena, es posible usar workbox-sw con URLs locales.

Conclusión

Ahora que sabes cómo usar Workbox sin almacenamiento previo en caché, ya no estás vinculado a un agrupador ni a una herramienta de compilación en particular. Esto te brinda la flexibilidad para crear de forma manual un service worker con solo los fragmentos del código de almacenamiento en caché del entorno de ejecución de Workbox que te interesan.