Skip to content

Releases: GoogleChrome/workbox

Workbox v6.0.0

30 Nov 20:11
Compare
Choose a tag to compare

Overview of Workbox v6

We're happy to announce the release of Workbox v6!

馃帀 What's New?

webpack improvements

This release includes additional bug fixes for better compatibility with webpack. As of this release, workbox-webpack-plugin requires webpack v4.40.0 or later (for those still on the v4.x branch) or webpack v.5.9.0 or later (for those who have updated to webpack v5.x).

workbox-webpack-plugin will also now take advantage of the immutable metadata that webpack automatically adds to hashed assets. In most cases, this means that explicitly using dontCacheBustURLMatching in your workbox-webpack-plugin configuration is no longer necessary.

See #2651, #2673, and #2675.

workbox-strategies improvements

The best way to ensure third-party developers have the power to extend Workbox in ways that fully meet their needs is to base our own strategies on top of the extensibility mechanisms we expose to third-party developers.

Specifically, v6 introduces a new way for third-party developers to define their own Workbox strategies, and all of our built-in strategies have been rewritten on top of this mechanism.

This change also allowed us to rewrite the workbox-precaching codebase to use workbox-strategies as a base. This should not result in any breaking changes, and should lead to better long-term consistency in how the two modules access the network and cache.

See #2446, #2459 and #2569 for more details.

New strategy base class

In v6, all Workbox strategy classes (both built-in strategies as well as custom, third-party strategies) must extend the new Strategy base class.

The Strategy base class is responsible for two primary things:

  • Invoking plugin lifecycle callbacks common to all strategy handlers (e.g. when they start, respond, and end).
  • Creating a "handler" instance, that can manage state for each individual request a strategy is handling.

A new "handler" class

We previously had internal modules call fetchWrapper and cacheWrapper, which (as their name implies) wrap the various fetch and cache APIs with hooks into their lifecycle. This is the mechanism that currently allows plugins to work, but it's not exposed to developers.

The new "handler" class (which this proposal calls StrategyHandler) will expose these methods so custom strategies can call fetch() or cacheMatch() and have any plugins that were added to the strategy instance automatically invoked.

This class would also make it possible for developers to add their own custom, lifecycle callbacks that might be specific to their strategies, and they would "just work" with the existing plugin interface.

New plugin lifecycle state

In Workbox v5, plugins are stateless. That means if a request for /index.html triggers both the requestWillFetch and cachedResponseWillBeUsed callbacks, those two callbacks have no way of communicating with each other or even knowing that they were triggered by the same request.

In this proposal, all plugin callbacks will also be passed a new state object. This state object will be unique to this particular plugin object and this particular strategy invocation (i.e. the call to handle()).

This allows developers to write plugins where one callback can conditionally do something based on what another callback in the same plugin did (e.g. compute the time delta between running requestWillFetch and fetchDidSucceed or fetchDidFail).

New plugin lifecycle callbacks

In order to fully leverage the plugin lifecycle state (mentioned above), you need to know when the lifecycle of a given strategy invocation starts and finishes.

To address this need (and others), the following new plugin lifecycle callbacks will be added:

  • handlerWillStart: called before any handler logic starts running. This callback can be used to set the initial handler state (e.g. record the start time).
  • handlerWillRespond: called before the strategies handle() method returns a response. This callback can be used to modify that response before returning it to a route handler or other custom logic.
  • handlerDidRespond: called after the strategy's handle() method returns a response. This callback can be used to record any final response details, e.g. after changes made by other plugins.
  • handlerDidComplete: called after all extend lifetime promises added to the event from the invocation of this strategy have settled. This callback can be used to report on any data that needs to wait until the handler is done in order to calculate (e.g. cache hit status, cache latency, network latency).
  • handlerDidError: called if the handler was unable to provide a valid response from any source. This callback can be used to provide "fallback" content as an alternative to a network error.

Developers implementing their own custom strategies do not have to worry about invoking these callbacks themselves; that's all handled by a new Strategy base class.

More accurate TypeScript types for handlers

TypeScript definitions for various callback methods have been normalized. This should lead to a better experience for developers who use TypeScript and write their own code to implement or call handlers.

See #2548.

workbox-recipes

This release includes a new module, workbox-recipes, that combines common routing and caching strategy configurations into ready-to-use code that can be dropped in to your service worker.

You can read more about what's included in the first batch of recipes, as well as how to use them, in #2664.

workbox-window improvements

New messageSkipWaiting() method

A new method, messageSkipWaiting(), has been added to the workbox-window module to simplify the process of telling the "waiting" service worker to activate.

This offers some improvements over alternatives:

  • It calls postMessage() with the de facto standard message body, {type: 'SKIP_WAITING'}, that a service worker generated by Workbox checks for to trigger skipWaiting().

  • It chooses the correct "waiting" service worker to post this message to, even if it's not the same service worker that workbox-window was registered with.

See #2394.

Removal of "external" events in favor of an isExternal property

Many developers were confused by the concept of "external" events in workbox-window, and in practice, they did not end up being a net-positive.

All "external" events are now represented as "normal" events with an isExternal property set to true. This allows developers who care about the distinction to still detect it, and developers who don't need to know can ignore the property.

See #2031.

Cleaner "Offer a page reload for users" recipe

Taken together, these two changes make the "Offer a page reload for users" recipe cleaner:

<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0/workbox-window.prod.mjs';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  const showSkipWaitingPrompt = () => {
    // This assumes a hypothetical createUIPrompt() method with
    // onAccept and onReject callbacks:
    const prompt = createUIPrompt({
      onAccept: () => {
        wb.addEventListener('controlling', () => {
          window.location.reload();
        });

        // This will postMessage() to the waiting service worker.
        wb.messageSkipWaiting();
      },

      onReject: () => {
        prompt.dismiss();
      }
    });
  };

  // Listening for externalwaiting is no longer needed.
  wb.addEventListener('waiting', showSkipWaitingPrompt);
  wb.register();
}
</script>

sameOrigin parameter in matchCallback functions

A new boolean parameter, sameOrigin, is passed to the matchCallback function used in workbox-routing. It's set to true if the request is for a same-origin URL, and false otherwise.

This simplifies some common boilerplate:

// In v5:
registerRoute(
  ({url}) => url.origin === self.location.origin &&
             url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'}),
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin &&
                         url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'}),
);

See #2487.

matchOptions are supported in workbox-expiration

You can now set matchOptions in workbox-expiration, which will then be passed through as the CacheQueryOptions to the underlying cache.delete() call. (Most developers won't need to do this.)

See #2206.

Precaching now processes entries one by one, not in bulk

workbox-precaching has been updated so that only one entry in the precache manifest is requested and cached at a time, instead of attempting to request and cache all of them at once (leaving it to the browser to figure out how to throttle).

This should reduce the likelihood of net::ERR_INSUFFICIENT_RESOURCES errors while precaching, and also should reduce the bandwidth contention between precaching and simultaneous requests made by the web app.

S...

Read more

Workbox v6.0.0-rc.0

16 Nov 16:43
Compare
Choose a tag to compare
Workbox v6.0.0-rc.0 Pre-release
Pre-release

Overview of Workbox v6

We're happy to announce the first release candidate of Workbox v6! We do not anticipate any more breaking changes in between now and the official v6 release.

In addition to the changes outlined in the previous release notes, the following has changed since Workbox v5.

馃帀 What's New?

workbox-recipes

This release includes a new module, workbox-recipes, that combines common routing and caching strategy configurations into ready-to-use code that can be dropped in to your service worker.

You can read more about what's included in the first batch of recipes, as well as how to use them, in #2664.

webpack v5 compatibility improvements

This release includes additional bug fixes for better compatibility with webpack. As of this release, workbox-webpack-plugin requires webpack v4.40.0 or later (for those still on the v4.x branch) or webpack v.5.4.0 or later (for those who have updated to webpack v5.x).

workbox-webpack-plugin will also now take advantage of the immutable metadata that webpack automatically adds to hashed assets. In most cases, this means that explicitly using dontCacheBustURLMatching in your workbox-webpack-plugin configuration is no longer necessary.

See #2651, #2673, and #2675.

Thanks!

Thank you to @dermoumi for their contributions to this release.

Installation of the latest pre-release version

We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.

Workbox v6.0.0-alpha.3

12 Oct 19:30
Compare
Choose a tag to compare
Pre-release

Overview of Workbox v6

We're happy to announce the third alpha release of Workbox v6! In addition to the changes outlined in the previous release notes, the following has changed since Workbox v5.

馃帀 What's New?

Under-the-hood workbox-precaching improvements

This release includes a substantial rewrite to the implementation of workbox-precaching, to build on top of other standard Workbox idioms (like Routes, Strategy subclasses, and custom plugins) as much as possible. There are a few breaking changes, described in the follow section, but they are mostly limited to uncommon use cases, when PrecacheController is instantiated directly. For the most part, these changes are meant to be invisible to developers, but should lead to be better consistency in how routing and request handling works across all of Workbox.

You can read more about what's change in #2638

webpack v5 compatibility

As of this release, workbox-webpack-plugin should be compatible with webpack v5.0.0. We have also raised the minimum required version of webpack to v4.4.0, which should be a straightforward upgrade for developers who need to remain on webpack v4.x.

While all of the public interfaces remain the same, signfifcant changes were made to the code used to determine which webpack assets make it into your precache manifest. These take advantage of new methods that were added in webpack v4.4.0, and which have to be used in webpack v5.0.0. We encourage developers to test workbox-webpack-plugin carefully, and raise issues if you find discrepencies like URLs missing from your precache manifest! This applies whether you are remaining on webpack v4.4.0, or are upgrade to webpack v5.0.0.

Note: At this time, workbox-webpack-plugin has issues detecting the correct URLs for HTML assets created by html-webpack-plugin in webpack v5.0.0. You can follow jantimon/html-webpack-plugin#1522 for updates.

cacheKeyWillBeUsed can be used to cache non-GET requests

Only GET requests can be used as cache keys, but there are scenarios in which you might want to use a combination of plugins to transform a POST or PUT request into a cacheable GET request.

You can now use the cacheKeyWillBeUsed lifecycle callback in a plugin to return a GET request with whatever URL you'd like to use as a cache key, and that can then allow the response associated with a POST or PUT to be cached.

See #2615 for more details. Thanks to @markbrocato for their contribution.

鈿狅笍 Breaking Changes

workbox-precaching

Note: The following changes primarily apply to direct usage of the PrecacheController class. Most developers don't use PrecacheController directly, and instead use static helper methods like precacheAndRoute() exported by workbox-precaching. [#2639]

  • The PrecacheController constructor now takes in an object with specific properties as its parameter, instead of a string. This object supports the following properties: cacheName (serving the same purpose as the string that was passed in to the constructor in v5), plugins (replacing the addPlugins() method from v5), and fallbackToNetwork (replacing the similar option that was passed to createHandler() and `createHandlerBoundToURL() in v5).

  • The install() and activate() methods of PrecacheController now take exactly one parameter, which should be set to a corresponding InstallEvent or ActivateEvent, respectively.

  • The addRoute() method has been removed from PrecacheController. In its place, the new PrecacheRoute class can be used to create a route that you can then register.

  • The precacheAndRoute() method has been removed from PrecacheController. (It still exists as a static helper method exported by the workbox-precaching module.) It was removed because PrecacheRoute can be used instead.

  • The createMatchCalback() method has been removed from PrecacheController. The new PrecacheRoute can be used instead.

  • The createHandler() method has been removed from PrecacheController. The strategy property of the PrecacheController object can be used to handle requests instead.

  • The createHandler() static export has already been removed from the workbox-precaching module. In its place, developers should construct a PrecacheController instance and use its strategy property.

  • The route registered with precacheAndRoute() is now a "real" route that uses workbox-routing's Router class under the hood. This may lead to a different evaluation order of your routes if you interleave calls to registerRoute() and precacheAndRoute(). See #1857 and #2402 for more details.

workbox-webpack-plugin

  • The minimum required version of webpack has been increased to v4.4.0. (See previous section for other webpack updates.) [#2641]

Installation of the latest pre-release version

We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.

Workbox v5.1.4

09 Sep 16:18
Compare
Choose a tag to compare

The v5.1.4 release contains a dependency update for rollup-plugin-terser, resolving a security error with one of its dependencies.

See #2601

Workbox v6.0.0-alpha.2

14 Aug 19:30
Compare
Choose a tag to compare
Pre-release

Workbox v6.0.0-alpha.2 includes updates to various underlying npm dependencies, but is otherwise identical to the previous v6.0.0-alpha.1 release.

Installation of the latest pre-release version

We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.

Workbox v6.0.0-alpha.1

23 Jul 18:43
Compare
Choose a tag to compare
Pre-release

Overview of Workbox v6

We're happy to announce the first alpha release of Workbox v6!

馃帀 What's New?

workbox-strategies improvements

The best way to ensure third-party developers have the power to extend Workbox in ways that fully meet their needs is to base our own strategies on top of the extensibility mechanisms we expose to third-party developers.

Specifically, v6 introduces a new way for third-party developers to define their own Workbox strategies, and all of our built-in strategies have been rewritten on top of this mechanism.

This change also allowed us to rewrite the workbox-precaching codebase to use workbox-strategies as a base. This should not result in any breaking changes, and should lead to better long-term consistency in how the two modules access the network and cache.

See #2446, #2459 and #2569 for more details.

New strategy base class

In v6, all Workbox strategy classes (both built-in strategies as well as custom, third-party strategies) must extend the new Strategy base class.

The Strategy base class is responsible for two primary things:

  • Invoking plugin lifecycle callbacks common to all strategy handlers (e.g. when they start, respond, and end).
  • Creating a "handler" instance, that can manage state for each individual request a strategy is handling.

A new "handler" class

We previously had internal modules call fetchWrapper and cacheWrapper, which (as their name implies) wrap the various fetch and cache APIs with hooks into their lifecycle. This is the mechanism that currently allows plugins to work, but it's not exposed to developers.

The new "handler" class (which this proposal calls StrategyHandler) will expose these methods so custom strategies can call fetch() or cacheMatch() and have any plugins that were added to the strategy instance automatically invoked.

This class would also make it possible for developers to add their own custom, lifecycle callbacks that might be specific to their strategies, and they would "just work" with the existing plugin interface.

New plugin lifecycle state

In Workbox v5, plugins are stateless. That means if a request for /index.html triggers both the requestWillFetch and cachedResponseWillBeUsed callbacks, those two callbacks have no way of communicating with each other or even knowing that they were triggered by the same request.

In this proposal, all plugin callbacks will also be passed a new state object. This state object will be unique to this particular plugin object and this particular strategy invocation (i.e. the call to handle()).

This allows developers to write plugins where one callback can conditionally do something based on what another callback in the same plugin did (e.g. compute the time delta between running requestWillFetch and fetchDidSucceed or fetchDidFail).

New plugin lifecycle callbacks

In order to fully leverage the plugin lifecycle state (mentioned above), you need to know when the lifecycle of a given strategy invocation starts and finishes.

To address this need (and others), the following new plugin lifecycle callbacks will be added:

  • handlerWillStart: called before any handler logic starts running. This callback can be used to set the initial handler state (e.g. record the start time).
  • handlerWillRespond: called before the strategies handle() method returns a response. This callback can be used to modify that response before returning it to a route handler or other custom logic.
  • handlerDidRespond: called after the strategy's handle() method returns a response. This callback can be used to record any final response details, e.g. after changes made by other plugins.
  • handlerDidComplete: called after all extend lifetime promises added to the event from the invocation of this strategy have settled. This callback can be used to report on any data that needs to wait until the handler is done in order to calculate (e.g. cache hit status, cache latency, network latency).
  • handlerDidError: called if the handler was unable to provide a valid response from any source. This callback can be used to provide "fallback" content as an alternative to a network error.

Developers implementing their own custom strategies do not have to worry about invoking these callbacks themselves; that's all handled by a new Strategy base class.

More accurate TypeScript types for handlers

TypeScript definitions for various callback methods have been normalized. This should lead to a better experience for developers who use TypeScript and write their own code to implement or call handlers.

See #2548.

workbox-window improvements

New messageSkipWaiting() method

A new method, messageSkipWaiting(), has been added to the workbox-window module to simplify the process of telling the "waiting" service worker to activate.

This offers some improvements over alternatives:

  • It calls postMessage() with the de facto standard message body, {type: 'SKIP_WAITING'}, that a service worker generated by Workbox checks for to trigger skipWaiting().

  • It chooses the correct "waiting" service worker to post this message to, even if it's not the same service worker that workbox-window was registered with.

See #2394.

Removal of "external" events in favor of an isExternal property

Many developers were confused by the concept of "external" events in workbox-window, and in practice, they did not end up being a net-positive.

All "external" events are now represented as "normal" events with an isExternal property set to true. This allows developers who care about the distinction to still detect it, and developers who don't need to know can ignore the property.

See #2031.

Cleaner "Offer a page reload for users" recipe

Taken together, these two changes make the "Offer a page reload for users" recipe cleaner:

<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  const showSkipWaitingPrompt = () => {
    // This assumes a hypothetical createUIPrompt() method with
    // onAccept and onReject callbacks:
    const prompt = createUIPrompt({
      onAccept: () => {
        wb.addEventListener('controlling', () => {
          window.location.reload();
        });

        // This will postMessage() to the waiting service worker.
        wb.messageSkipWaiting();
      },

      onReject: () => {
        prompt.dismiss();
      }
    });
  };

  // Listening for externalwaiting is no longer needed.
  wb.addEventListener('waiting', showSkipWaitingPrompt);
  wb.register();
}
</script>

sameOrigin parameter in matchCallback functions

A new boolean parameter, sameOrigin, is passed to the matchCallback function used in workbox-routing. It's set to true if the request is for a same-origin URL, and false otherwise.

This simplifies some common boilerplate:

// In v5:
registerRoute(
  ({url}) => url.origin === self.location.origin &&
             url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'}),
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin &&
                         url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'}),
);

See #2487.

matchOptions are supported in workbox-expiration

You can now set matchOptions in workbox-expiration, which will then be passed through as the CacheQueryOptions to the underlying cache.delete() call. (Most developers won't need to do this.)

See #2206.

Precaching now processes entries one by one, not in bulk

workbox-precaching has been updated so that only one entry in the precache manifest is requested and cached at a time, instead of attempting to request and cache all of them at once (leaving it to the browser to figure out how to throttle).

This should reduce the likelihood of net::ERR_INSUFFICIENT_RESOURCES errors while precaching, and also should reduce the bandwidth contention between precaching and simultaneous requests made by the web app.

See #2528.

PrecacheFallbackPlugin allows for easier offline fallback

workbox-precaching now includes a PrecacheFallbackPlugin, which implements the new handlerDidError lifecycle method added in v6.

This makes it easy to specify a precached URL as a "fallback" for a given strategy when a response otherwise wouldn't be available. The plugin will take care of properly constructing the correct cache key for the precached URL, including any revision parameter that's needed.

Here's a sample of using it to respond with a precached /offline.html when the NetworkOnly strategy can't generate a response for a navigation request鈥攊n other words, displaying a custom offline HTML page:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fa...
Read more

Workbox v5.1.3

24 Apr 16:35
Compare
Choose a tag to compare

馃悰 What's Fixed?

workbox-build

  • Correct workbox-build's getManifest() JSDoc [#2429]

workbox-cli

  • Don't check swSrc for hardcoded injection point in wizard flow [#2451]

workbox-core

  • handlerCallback JSDocs update [#2440]

workbox-precaching

  • Remove the isSWEnv assertion [#2453]
  • Update message to remove duplicate is [#2466]

Thanks!

Special thanks to @akonchady for contributing a PR that went in to this release.

Workbox v5.1.2

25 Mar 14:40
Compare
Choose a tag to compare

馃悰 What's Fixed?

workbox-build

  • Reverted the strip-comments dependency to an earlier revision, to provide continued compatibility with the v8.x.y releases of node. [#2416]

Thanks!

Special thanks to @Mister-Hope for raising issues that were resolved in this release.

Workbox v5.1.1

19 Mar 19:07
Compare
Choose a tag to compare

(We ran into some issues with the v5.1.0 release process, so v5.1.1 is a republish of the same code.)

馃帀 What's New?

workbox-routing

  • Adjusted the debug logging code so that a URL's hash portion is displayed. [#2371]

workbox-webpack-plugin

  • A new compileSrc option (defaulting to true) has been added. If set to false, then webpack will not run the swSrc file through a compilation. This can be useful if you want your swDest output to be, e.g., a JSON file which contains your precache manifest. [#2412]

馃悰 What's Fixed?

workbox-webpack-plugin

  • Switch to official package exports when using internal webpack modules. [#2397]
  • webpackCompilationPlugins that customize the swSrc compilation should now be properly applied. [#2400]

Thanks!

Special thanks to @aritsune, @bailnl, @novaknole and @pizzafox for raising issues that were resolved in this release.

Workbox v5.0.0

29 Jan 02:56
Compare
Choose a tag to compare

Overview of Workbox v5

We're happy to announce the release of Workbox version 5! This release introduces a lot of new features, as well as some breaking changes.

If you're already using Workbox, the best place to get up to speed is the guide to migrating from v4 to v5.

One example migration, with commentary, can be found in this GitHub commit.

馃帀 What's New?

A shift towards local Workbox bundles & away from the CDN

While our immediate plan is to continue publishing copies of the Workbox runtime code to our CDN, in v5, the generateSW mode of our build tools will create a local bundle of exactly the Workbox runtime methods you end up using in your service worker. Depending on the value of inlineWorkboxRuntime, this bundle will either be imported from a separate file, or inlined directly in your top-level service worker.

Under the hood, we use Rollup to create this optimized bundle, optionally minifying it and generating sourcemaps, depending on the configuration.

See #2064 for more details.

If you're using the workbox-webpack-plugin's InjectManifest mode, the service worker file you specify via swSrc will end up being run through a webpack compilation process, optionally applying any compilation plugins configured via the webpackPlugins parameter. This should simplify the development flow described in the Using Bundlers (webpack/Rollup) with Workbox guide.

See #1513 for more details.

You can continue using importScripts('http://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js') and relying on workbox-sw to dynamically pull in the Workbox runtime code that you need in v5, but we expect that using a custom bundle will lead to smaller runtime payloads (as well as work around issues with asynchronous imports), and we encourage developers to consider switching off of the CDN.

Changes to the webpack precache manifest

Before v5, workbox-webpack-plugin would generate a list of entries to precache based on two distinct sources: the set of assets in a webpack compilation, along with an optional additional set of files matched via glob patterns. Most webpack developers did not use the glob-related options (since the webpack compilation would normally include all the assets that they cared about), but at the same time, some helpful configuration options for manipulating or post-processing the precache manifest only applied to entries created via those glob patterns.

In v5, the glob-related configuration options are no longer supported. The webpack asset pipeline is the source of all the automatically created manifest entries. (Developers who have files that exist outside of the webpack asset pipeline are encouraged to use, e.g., copy-webpack-plugin to get those files into the webpack compilation.)

Beyond that, options for post-processing the precache manifest can now be used to manipulate entries that originate from the webpack asset pipeline. manifestTransforms, in particular, can be used to make arbitrary changes to any aspect of the precache manifest, including adding entries, deleting them, and changing their revision or url fields as needed. The current webpack compilation will be passed in to the callback function in case you need information from there to determine how to manipulate entries.

Here's an example of using manifestTransforms to perform extensive post-processing of a precache manifest:

const manifestTransform = (originalManifest, compilation) => {
  // If anything needs to be propagated to webpack's list
  // of compilaiton warnings, add the message here:
  const warnings = [];

  const manifest = originalManifest.map((entry) => {
    // entry has size, revision, and url fields.

    // Add a CDN prefix to certain URLs.
    // (alternatively, use modifyURLPrefix)
    if (entry.url.endsWith('.jpg')) {
      entry.url = `https://examplecdn.com/${entry.url}`;
    }

    // Remove revision when there's a match for your hashed URL pattern.
    // (alternatively, just set dontCacheBustURLsMatching)
    if (entry.url.match(/\.[0-9a-f]{6}\./)) {
      delete entry.revision;
    }

    // Exclude assets greater than 1MB, unless they're JPEGs.
    // (alternatively, use maximumFileSizeToCacheInBytes)
    if ((entry.size > 1024 * 1024) && !entry.url.endsWith('.jpg')) {
      warnings.push(`${entry.url} will not be precached because it is too big.`);
      return null;
    }

    return entry;
  }).filter(Boolean); // Exclude any null entries.

  // When manually adding in additional entries, make sure you use a URL
  // that already includes versioning info, like the v1.0.0 below:
  manifest.push({
    url: 'https://examplecdn.com/third-party-code/v1.0.0/index.js',
  });

  return {manifest, warnings};
};

Helpers that implement common manifest transformations, like maximumFileSizeToCacheInBytes, dontCacheBustURLsMatching and modifyURLPrefix, are also supported for webpack assets.

See #1591 and #1854.

Additionally, in v5, the precache manifest is inlined into the top-level service worker file, and not stored in a separate, external JavaScript file.

Simplified injectManifest placeholder replacement

Prior to v5, manifest injection worked by using a regular expression to find the correct location in the source service worker file to replace with the array of manifest entries. This could be brittle, and it was hard to customize, since the replacement step assumed you were using a RegExp that had capture groups.

This is simplified in v5, and using the injectManifest mode just checks for a placeholder variable and performs the equivalent of string replacement to inject the full manifest in its place. This variable is self.__WB_MANIFEST by default.

Your swSrc file in v4 might have looked like precacheAndRoute([]);

In v5, you should change this to precacheAndRoute(self.__WB_MANIFEST);

self.__WB_MANIFEST was chosen as the default replacement because self should always be defined in the service worker global scope, and it is unlikely to conflict with any user-created variables. If you need a different replacement, it can be configured via the injectionPoint option.

See #2059 for more details.

TypeScript support

All browser-based Workbox packages are now written in TypeScript and type definitions have been published to npm. TypeScript users (as well as users with TypeScript-aware code editors) can now get type checking for all browser-exposed Workbox APIs. (There are no TypeScript definitions for the various Workbox build tools at this time.)

To get type definitions for any Workbox APIs, you can import the package as described in our guide on Using Bundlers (webpack/Rollup) with Workbox. For example:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {Plugin as ExpirationPlugin} from 'workbox-expiration';

registerRoute(
  /\.(?:png|gif|jpg|jpeg|svg)$/,
  new CacheFirst({
    cacheName: 'images',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 60,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
      }),
    ],
  }),
);

Note, we've historically published our Workbox source modules with the .mjs extension as a way to disambiguate them from classic scripts and the examples in our documentation that reference file paths always use .mjs.

However, since TypeScript does not currently support importing .mjs files we publish both .js and .mjs files to npm. TypeScript users wanting to import an individual module should be able to reference it by omitting the extension (which will then default to the .js file).

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {Plugin as ExpirationPlugin} from 'workbox-expiration';

If you encounter any problems with the type definitions or importing the source files via TypeScript, please let us know by opening an issue on GitHub.

additionalManifestEntries option in build tools

All of the build tools (generateSW and injectManifest modes in workbox-build, workbox-cli, and workbox-webpack-plugin) now support a new option: additionalManifestEntries. [#2124] It can be set to a list of additional precache manifest entries that go beyond what would normally be included as part of your build (such as CDN URLs), and is a shortcut to something that is otherwise possible via the manifestTransforms option.

Before using this feature, please keep in mind that workbox-precaching requires one of two things from each entry in order to keep precached content up to date:

  • The URL contains versioning information, and therefore the contents will never change. E.g. 'https://example.com/v...
Read more