CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue--cli-plugin-pwa

Vue CLI plugin that adds Progressive Web App capabilities including service workers, manifests, and PWA meta tags

Pending
Overview
Eval results
Files

service-worker.mddocs/

Service Worker Management

Service worker generation for production builds using Workbox webpack plugin integration, and development middleware that serves no-op service workers to prevent caching issues during development.

Capabilities

Development Middleware

Creates Express middleware that serves a no-op service worker during development to prevent production service worker caching issues.

/**
 * Creates development middleware for serving no-op service worker
 * @returns {Function} Express middleware function that intercepts /service-worker.js requests
 */
function createNoopServiceWorkerMiddleware(): (req: Request, res: Response, next: NextFunction) => void;

Usage Example:

const createNoopServiceWorkerMiddleware = require('@vue/cli-plugin-pwa/lib/noopServiceWorkerMiddleware');
const express = require('express');

const app = express();
app.use(createNoopServiceWorkerMiddleware());

// When accessing /service-worker.js in development, serves the no-op service worker

No-op Service Worker Script

The actual service worker script served during development that resets any existing service workers.

// Development service worker content
self.addEventListener('install', () => self.skipWaiting());
self.addEventListener('fetch', () => {});
self.addEventListener('activate', () => {
  self.clients.matchAll({ type: 'window' }).then(windowClients => {
    for (const windowClient of windowClients) {
      windowClient.navigate(windowClient.url);
    }
  });
});

Production Service Worker Generation

In production builds, the plugin integrates with Workbox webpack plugin to generate actual service workers with precaching capabilities.

/**
 * Workbox plugin integration for production service worker generation
 * Applied automatically when NODE_ENV === 'production'
 */
interface WorkboxIntegration {
  /** Plugin mode: 'GenerateSW' (default) or 'InjectManifest' */
  workboxPluginMode: 'GenerateSW' | 'InjectManifest';
  /** Configuration passed to Workbox webpack plugin */
  workboxOptions: WorkboxOptions;
}

Workbox Plugin Modes

Two service worker generation strategies provided by Workbox.

/**
 * GenerateSW Mode - Automatically generates complete service worker
 * Best for: Simple PWAs with standard caching needs
 */
interface GenerateSWMode {
  mode: 'GenerateSW';
  options: {
    /** Cache identifier for service worker */
    cacheId?: string;
    /** Files to exclude from precaching */
    exclude?: RegExp[];
    /** Whether to skip waiting during service worker updates */
    skipWaiting?: boolean;
    /** Whether to claim clients immediately */
    clientsClaim?: boolean;
    /** Runtime caching strategies */
    runtimeCaching?: RuntimeCachingEntry[];
  };
}

/**
 * InjectManifest Mode - Injects precache manifest into existing service worker
 * Best for: Custom service worker logic with precaching
 */
interface InjectManifestMode {
  mode: 'InjectManifest';
  options: {
    /** Path to source service worker file */
    swSrc: string;
    /** Files to exclude from precaching */
    exclude?: RegExp[];
    /** Additional Workbox options */
    [key: string]: any;
  };
}

Runtime Caching Configuration

Configuration for caching strategies applied to runtime requests.

interface RuntimeCachingEntry {
  /** URL pattern to match for caching */
  urlPattern: RegExp | string;
  /** Caching strategy handler */
  handler: 'CacheFirst' | 'NetworkFirst' | 'NetworkOnly' | 'CacheOnly' | 'StaleWhileRevalidate';
  /** Additional caching options */
  options?: {
    /** Custom cache name */
    cacheName?: string;
    /** Network timeout for NetworkFirst strategy */
    networkTimeoutSeconds?: number;
    /** Cache expiration settings */
    expiration?: {
      maxEntries?: number;
      maxAgeSeconds?: number;
    };
    /** Background sync settings */
    backgroundSync?: {
      name: string;
      options?: any;
    };
  };
}

Usage Examples:

// GenerateSW mode with runtime caching
module.exports = {
  pwa: {
    workboxPluginMode: 'GenerateSW',
    workboxOptions: {
      skipWaiting: true,
      clientsClaim: true,
      runtimeCaching: [
        {
          urlPattern: /^https:\/\/api\.example\.com\//,
          handler: 'NetworkFirst',
          options: {
            cacheName: 'api-cache',
            networkTimeoutSeconds: 3,
            expiration: {
              maxEntries: 50,
              maxAgeSeconds: 300 // 5 minutes
            }
          }
        },
        {
          urlPattern: /\.(?:png|jpg|jpeg|svg)$/,
          handler: 'CacheFirst',
          options: {
            cacheName: 'images',
            expiration: {
              maxEntries: 100,
              maxAgeSeconds: 86400 // 24 hours
            }
          }
        }
      ]
    }
  }
};
// InjectManifest mode with custom service worker
module.exports = {
  pwa: {
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      swSrc: 'src/sw.js',
      exclude: [/\.map$/, /manifest$/, /\.htaccess$/]
    }
  }
};

// src/sw.js - Custom service worker
import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

// Precache and route static assets
precacheAndRoute(self.__WB_MANIFEST);
cleanupOutdatedCaches();

// Custom runtime caching
registerRoute(
  ({ request }) => request.destination === 'document',
  new StaleWhileRevalidate({
    cacheName: 'pages-cache'
  })
);

Default Exclusions

Files excluded from precaching by default.

const defaultExclusions = [
  /\.map$/,           // Source maps
  /img\/icons\//,     // PWA icons (served separately)
  /favicon\.ico$/,    // Favicon
  /^manifest.*\.js?$/ // Manifest files
];

Service Worker Validation

The plugin validates Workbox plugin mode against available options.

/**
 * Validates workboxPluginMode against available Workbox webpack plugin modes
 * @param {string} mode - The specified workbox plugin mode
 * @throws {Error} When mode is not supported
 */
if (!(workboxPluginMode in workboxWebpackModule)) {
  throw new Error(
    `${workboxPluginMode} is not a supported Workbox webpack plugin mode. ` +
    `Valid modes are: ${Object.keys(workboxWebpackModule).join(', ')}`
  );
}

Client Service Worker Registration

Template for registering service workers in the client application.

// Generated registerServiceWorker.js template
import { register } from 'register-service-worker';

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready() {
      console.log('App is being served from cache by a service worker.');
    },
    registered() {
      console.log('Service worker has been registered.');
    },
    cached() {
      console.log('Content has been cached for offline use.');
    },
    updatefound() {
      console.log('New content is downloading.');
    },
    updated() {
      console.log('New content is available; please refresh.');
    },
    offline() {
      console.log('No internet connection found. App is running in offline mode.');
    },
    error(error) {
      console.error('Error during service worker registration:', error);
    }
  });
}

Install with Tessl CLI

npx tessl i tessl/npm-vue--cli-plugin-pwa

docs

html-integration.md

index.md

plugin-configuration.md

project-generation.md

service-worker.md

tile.json