A plugin for your Webpack build process, helping you generate a manifest of local files that workbox-sw should precache.
Overall
score
80%
The InjectManifest plugin takes an existing service worker source file and injects a precache manifest based on webpack assets. This allows you to write custom service worker logic while still benefiting from automatic asset precaching.
Creates a webpack plugin that compiles an existing service worker and injects a precache manifest into it.
/**
* Creates an instance of InjectManifest plugin
* @param config - Configuration options for manifest injection
*/
class InjectManifest {
constructor(config: WebpackInjectManifestOptions);
/**
* Webpack plugin interface method - called by webpack during compilation
* @param compiler - Webpack compiler instance
*/
apply(compiler: webpack.Compiler): void;
}Usage Examples:
import { InjectManifest } from "workbox-webpack-plugin";
// Basic configuration
new InjectManifest({
swSrc: './src/service-worker.js',
swDest: 'sw.js',
});
// Advanced configuration with compilation options
new InjectManifest({
swSrc: './src/sw.ts', // TypeScript source
swDest: 'service-worker.js',
compileSrc: true,
exclude: [/\.map$/, /manifest$/],
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
webpackCompilationPlugins: [
// Additional webpack plugins for service worker compilation
],
});Your source service worker file must include an injection point where the manifest will be inserted:
// src/service-worker.js
import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
// This will be replaced with the actual precache manifest
precacheAndRoute(self.__WB_MANIFEST);
// Optional: clean up outdated caches
cleanupOutdatedCaches();
// Add custom caching logic
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({
cacheName: 'images',
plugins: [{
cacheKeyWillBeUsed: async ({ request }) => {
return `${request.url}?version=1`;
},
}],
})
);
// Custom event listeners
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});interface WebpackInjectManifestOptions {
/** Additional entries to include in the precache manifest */
additionalManifestEntries?: Array<ManifestEntry | string>;
/** Whether to compile the service worker source through webpack */
compileSrc?: boolean;
/** Files to exclude from precaching */
exclude?: Array<RegExp | string | ((asset: {name: string}) => boolean)>;
/** Webpack chunks to exclude from precaching */
excludeChunks?: Array<string>;
/** URL parameters to ignore when matching precached URLs */
ignoreURLParametersMatching?: Array<RegExp>;
/** String to replace with the precache manifest (defaults to 'self.__WB_MANIFEST') */
injectionPoint?: string;
/** Functions to transform the precache manifest */
manifestTransforms?: Array<ManifestTransform>;
/** Maximum file size (in bytes) to include in precache */
maximumFileSizeToCacheInBytes?: number;
/** Build mode - affects optimization and debugging */
mode?: 'development' | 'production';
/** Output filename for the compiled service worker */
swDest?: string;
/** Path to the source service worker file */
swSrc: string;
/** Additional webpack plugins to apply during service worker compilation */
webpackCompilationPlugins?: Array<any>;
}By default, the plugin looks for self.__WB_MANIFEST in your service worker source and replaces it with the actual precache manifest. You can customize this:
new InjectManifest({
swSrc: './src/sw.js',
injectionPoint: 'MY_CUSTOM_MANIFEST',
});Then in your service worker:
// src/sw.js
import { precacheAndRoute } from 'workbox-precaching';
// Use custom injection point
precacheAndRoute(MY_CUSTOM_MANIFEST);When using TypeScript for your service worker, enable compilation:
new InjectManifest({
swSrc: './src/service-worker.ts',
swDest: 'sw.js',
compileSrc: true, // Enable TypeScript compilation
webpackCompilationPlugins: [
// Add any additional plugins needed for TS compilation
],
});Your TypeScript service worker:
// src/service-worker.ts
import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching';
import { registerRoute, NavigationRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';
declare const self: ServiceWorkerGlobalScope;
// Precache and route static assets
precacheAndRoute(self.__WB_MANIFEST);
cleanupOutdatedCaches();
// Handle navigation requests
const navigationRoute = new NavigationRoute(
new NetworkFirst({
cacheName: 'navigations',
})
);
registerRoute(navigationRoute);
// Type-safe event handling
self.addEventListener('message', (event: ExtendableMessageEvent) => {
if (event.data?.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});Transform the generated manifest before injection:
interface ManifestTransform {
(originalManifest: Array<ManifestEntry>, compilation?: webpack.Compilation): Promise<{
manifest: Array<ManifestEntry>;
warnings?: Array<string>;
}> | {
manifest: Array<ManifestEntry>;
warnings?: Array<string>;
};
}
interface ManifestEntry {
url: string;
revision: string | null;
}Example manifest transform:
const customTransform = (originalManifest, compilation) => {
// Add cache busting parameter to all URLs
const manifest = originalManifest.map(entry => ({
...entry,
url: `${entry.url}?v=${Date.now()}`,
}));
return { manifest };
};
new InjectManifest({
swSrc: './src/sw.js',
manifestTransforms: [customTransform],
});The plugin integrates with webpack's compilation process and handles both webpack 4 and 5:
compileSrc is enabledInstall with Tessl CLI
npx tessl i tessl/npm-workbox-webpack-pluginevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10