Usa Workbox sin almacenamiento previo en caché

Hasta ahora, esta documentación se ha centrado en el almacenamiento en caché previo y, a menudo, se hace referencia a las herramientas de compilación generateSW y injectManifest. Si bien hay muchos buenos motivos para incluir lógica de almacenamiento en caché previo en tu trabajador de servicio, no es necesario que uses el almacenamiento en caché previo para usar Workbox.

Tal vez tu proyecto solo necesite almacenamiento en caché del entorno de ejecución, o tal vez quieras una forma más sencilla de integrar las APIs de service worker, como 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 explica en este artículo.

Cuando se usa un empaquetador

Los agrupadores son importantes en el panorama del desarrollo web y es probable que tu proyecto use uno. Si este es el caso, es importante saber que no necesitas usar un complemento de empaquetador (como workbox-webpack-plugin) si no estás almacenando en caché nada de antemano. Tratarás a tu service worker como un punto de entrada independiente en tu aplicación.

En la raíz del directorio de origen de tu proyecto, crearás un trabajador de servicio y usarás los módulos de Workbox que requiera tu aplicación. A continuación, se muestra un ejemplo sin almacenamiento en caché previo que configura estrategias de almacenamiento en caché para las solicitudes de recursos de imagen y navegación en instancias de Cache independientes:

// 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 este punto, solo debes especificar este trabajador de servicio como punto de entrada en el empaquetador que elijas. A continuación, se incluyen algunos ejemplos de cómo hacerlo en algunos empaquetadores populares.

webpack

webpack acepta puntos de entrada en su configuración entry. Hay un par de cosas que debes tener en cuenta cuando utilizas este enfoque:

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

Para satisfacer las condiciones anteriores, se puede pasar una función a output.filename que examine si el punto de entrada actual que se está procesando es el punto de entrada del trabajador de servicio. De lo contrario, los archivos con control de versiones 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
  }
};

propiedad de datos integrados

Rollup es una situación similar a webpack, excepto que se especifican varios puntos de entrada como objetos de configuración separados 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')
      })
    ]
  }
];

esbuild

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 empaquetador 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 desde una CDN dentro de tu trabajador de servicio 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 perspectiva de cargar el entorno de ejecución de Workbox desde una CDN no parece ser muy buena, puedes usar workbox-sw con URLs locales.

Conclusión

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