Skip to content

Releases: GoogleChrome/workbox

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

Workbox v5.0.0-rc.2

21 Jan 21:42
Compare
Choose a tag to compare
Workbox v5.0.0-rc.2 Pre-release
Pre-release

The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-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.

🎉 What's New?

Improvements to the JSDoc documentation for all of the build tools. [#2320]

⚠️ Breaking Changes

whitelist/blacklist (in the NavigationRoute class) and navigateFallbackWhitelist/navigateFallbackBlacklist (in the build tools) have been renamed to allowlist/denylist and navigateFallbackAllowlist/navigateFallbackDenylist. Functionality remains the same. [#2325]

🐛 What's Fixed?

workbox-build

  • Consistently use absolute file paths in the return value of the injectManifest mode. [#2301]
  • Set revision: null instead of deleting the revision property when the build tool determines that the revision isn't necessary. [#2326]

workbox-core

  • No longer overwrites a __WB_DISABLE_DEV_LOGS value that's explicitly set by your service worker script. [#2296]

workbox-strategies

  • The handle() method of each strategy now supports passing in a string URL as the request property, matching the behavior of the (now deprecated) makeRequest() method. [#2317]

Workbox v5.0.0-rc.1

26 Nov 15:04
Compare
Choose a tag to compare
Workbox v5.0.0-rc.1 Pre-release
Pre-release

The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-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.

🎉 What's New?

All browser packages

  • A new __WB_DISABLE_DEV_LOGS global has been added to disable all logging in development mode. [#2284]

workbox-precaching

  • Calling precache()/precacheAndRoute() and passing in an precache manifest entry that is just a string has been deprecated. It will trigger a warning message in v5, and will be treated as a runtime error in a future release. If you need to use a hardcoded URL as a manifest entry, first ensure that it contains inline revision information, like a hash. Then, instead of passing in a string like '/app.1234abcd.js', use {url: '/app.1234abcd.js', revision: null} to explicitly state that the revision is meant to be null. [#2262]

🐛 What's Fixed?

workbox-routing

  • Fixed a ReadableStream bug in development mode in Safari. [#2268]

workbox-precaching

  • Fixed a bug where the result of the cacheWillUpdate() plugin callback was not being await-ed. [#2287]

Workbox v5.0.0-rc.0

17 Oct 13:47
Compare
Choose a tag to compare
Workbox v5.0.0-rc.0 Pre-release
Pre-release

The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-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.

🎉 What's New?

TypeScript

  • All public workbox types are now exported directly from workbox-core [#2255]
  • All packages have switched to using "strict": true in their TypeScript config. [#2241, #2244, #2256 2246]

workbox-precaching

  • Two new methods (matchPrecache() and createHandler()) have been added to make it easier to manually access precached assets. [#2254]

🐛 What's Fixed?

workbox-webpack-plugin

  • Missing source map assets are is no longer treated as a fatal error. [#2251]

  • If the swSrc file has an associated sourcemap, we now update that to account for the injected manifest. [#2239]

⚠️ Breaking Changes

workbox-precaching

  • The createHandlerForURL() method has been renamed to createHandlerBoundToURL() to make its intended usage more clear. [#2254]

Workbox v5.0.0-beta.1

02 Oct 17:46
Compare
Choose a tag to compare
Workbox v5.0.0-beta.1 Pre-release
Pre-release

The latest beta release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-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.

🐛 What's Fixed?

TypeScript

  • Various type annotations have been updated for accuracy. [#2200, #2208]

All build tools

  • If the swSrc file has an associated sourcemap, we now update that to account for the injected manifest. [#2239]

workbox-build

  • Fixed a bug that could lead to the output directory being prepended twice when writing the service worker to disk. [#2223]

  • Make sure that all swSrc and swDest files are left out of the generated precache manifest. [#2232]

workbox-broadcast-update

  • Added a check to wait for the resulting client to load on navigation requests before broadcasting any update messages. [#2210]

workbox-precaching

  • Instead of adding the __WB_REVISION__ query parameter to outgoing network requests that should be cache-busted, explicitly set the cache mode to 'reload' if needed. When cache-busting is not needed, set cache to 'default'. [#2222]

workbox-range-requests

  • Fixed a bug causing an invalid 206 Partial Content response to be used when the incoming request used Range: bytes=0-. [#2237]

workbox-webpack-plugin

  • Fixed an edge case that could lead to build errors when other plugins generate assets. [#2219]

workbox-window

  • The message event listener is now added earlier, inside of the constructor rather than the register() method. [#2211]

Thanks

Special thanks to @lukas2005 for their bug reports, and @azizhk for their contributions that went into this release!

Workbox v5.0.0-beta.0

21 Aug 20:04
Compare
Choose a tag to compare
Workbox v5.0.0-beta.0 Pre-release
Pre-release

🎉 What's New?

The latest beta release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.

workbox-broadcast-update

A generatePayload() configuration option has been added to the BroadcastCacheUpdate and BroadcastUpdatePlugin classes that allows developers to customize the message that gets sent to the window when a cached response has been udpated.

The generatePayload() function is called with the same arguments as the cacheDidUpdate() plugin callback, and its return value will be used as the message payload. Here's an example that adds the Last-Modified header value of the updated response to the payload:

new BroadcastUpdatePlugin({
  generatePayload({request, newResponse}) {
    return {
      url: request.url,
      lastModified: newResponse.headers.get('Last-Modified'),
    };
  },
});

workbox-core

A copyResponse() method has been added that can be used to clone a response and modify its headers, status, or statusText. [#2193]

Here's an example that adds a custom header to indicate that a response came from the cache (and not the network):

const newResponse = copyResponse(oldResponse, (responseInit) => {
  responseInit.headers.set('X-Cache', 'hit');
  return responseInit;
});

workbox-precaching

If workbox-precaching needs to bypass the HTTP cache when requesting a URL, it will now set cache: 'reload' on the outgoing Request, which in turns sets the appropriate Cache-Control headers. [#2176]

Previously, bypassing the HTTP cache was done by adding in a __WB_REVISION=... URL query parameter to the outgoing network request, meaning that backend web servers would see requests for URLs containing those query parameters. With this change in place, requests for URLs with __WB_REVISION=... should no longer be seen in HTTP server logs.

Please note that this change only applies to outgoing HTTP requests used to populate the precache, and does not apply to cache keys. The keys for some entries created by workbox-precaching still include the __WB_REVISION=... parameter, and it's still a best practice to call getCacheKeyForURL() to determine the actual cache key, including the __WB_REVISION parameter, if you need to access precached entries using the Cache Storage API directly.

All build tools

Any manifestTransform callbacks are now treated as being async, and each callback will be await-ed by the build tools. If you supply multiple transforms, they will still be run sequentially, in the same order. [#2195]

This should not be a breaking change, as you can continue providing non-async callback functions, and they will still work as before.

workbox-build and workbox-cli

As part of a general refactoring of how the options passed to all of our build tools are parsed [#2191], using precaching in the generateSW mode of workbox-build and workbox-cli is no longer mandatory. You can now use the runtimeCaching options without configuring the glob-related options, and your generated service worker will just contain the corresponding runtime caching routes.

If you don't configure the glob-related options and you don't use runtimeCaching, that will lead to a build error.

⚠️ Breaking Changes

workbox-broadcast-update

The workbox-broadcast-update package no longer uses BroadcastChannel, even in cases when the browser supports it. Instead it uses postMessage() to message window clients. [#2184]

This change was made because postMessage() messages are automatically buffered by the window to handle cases where the service worker sends a message before the code running on the window is ready to receive it. BroadcastChannel has no such buffering, and thus you're more likely to miss message when using it.

If you're currently listening for BroadcastChannel messages in your code running on the window, you'll now need to listen for message events on the ServiceWorkerContainer:

navigator.serviceWorker.addEventListener('message', (event) => {
  console.log(event.data);
})

Note: workbox-window users should not need to make any changes, as its internal logic has been updated to listen for postMessage() calls.

Plugin classes

  • All Plugin classes have been renamed to be package-specific, e.g. ExpirationPlugin, CacheableResponsePlugin, etc. If you're using one of the Workbox build tools in generateSW mode to create your service worker, this change will be handled for you automatically. If you use one of the plugins in a manually created service worker, you'll need to explicitly change instances of Plugin to the correct revised class name. [#2187]

🐛 What's Fixed?

workbox-routing

  • A RouteHandlerObject type has been added to fix TypeScript typing issue when using strategy classes as route handlers. [#2183]

workbox-webpack-plugin

  • importScriptsViaChunks will only call importScripts() on assets in that chunk which have a .js extension. [#2164]
  • The GenerateSW mode will now work properly when there are multiple compilations (via, e.g., webpack-dev-server). [#2167]
  • The json-stable-stringify dependency has been replaced by fast-json-stable-stringify. [#2163]
  • When using multiple instances of workbox-webpack-plugin in the same compilation, assets created by those other instances will now be excluded from each others' precache manifest. [#2182]

Thanks

Special thanks to @kaykayehnn for their bug reports and contributions that went into this release.

Workbox v5.0.0-alpha.2

01 Aug 21:18
Compare
Choose a tag to compare
Pre-release

🎉 What's New?

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/v1.0.0/index.js', or 'https://example.com/index.hashValue.js'

  • You include a revision field alongside an unversioned URL, providing versioning information that is updated each time new contents are deployed to that URL. E.g. {url: https://example.com/index.js, revision: hashOfIndexJsContents}

The precache manifest entries generated by Workbox's built tools can automatically add in revision fields for you, but when using additionalManifestEntries, it's up to you to ensure that you only add in versioned URLs, or that you include a revision field that will always change whenever the corresponding URL changes.

To ensure that developers are aware of this, passing in string values in the additionalManifestEntries will result in a non-fatal warning message, asking you tot confirm that your URLs are versioned. To avoid this message, pass in an object with a revision: null property instead of a string, like {url: http://example.com/v1.0.0/index.js, revision: null}.

importScriptsViaChunks in workbox-webpack-plugin's GenerateSW mode

A new option, importScriptsViaChunks, is supported in the GenerateSW mode of the webpack plugin. [#2131] Passing in one or more chunk names will cause the corresponding script files to be included in the generated service worker, via importScripts().

Because of the way script caching works with importScripts(), developers should ensure that their chunks' filenames include a hash, so that changes to a chunk's contents will result in new filename.

Support for subresource integrity metadata in precaching requests

Precache manifest entries can now include an optional property, integrity. If provided, that value will be treated as the integrity metadata for in the fetch() request used to populate the precache. [#2141]

There is currently no option in the Workbox build tools for generating this metadata; it's left as an exercise to developers to uses the manifestTransforms option to post-process the generated precache manifests and add in integrity properties, with appropriate values, to the entries that need that extra validation.

update(), to force a service worker update check

A new update() method has been added to workbox-window. When called, it will invoke the update() method on the underlying ServiceWorkerRegistration object. [#2136]

Calling this method is optional, as browsers will automatically check for service worker updates whenever there's a navigation request to a new page, along with a few other scenarios. However, as described in this guide, manually requesting a service worker update can be useful for loong-lived, single-page apps.

🚧 Breaking Changes

Removal of makeRequest() in favor of handle()

Calling makeRequest() is mostly equivalent to calling handle() on one of the workbox-strategy classes. The differences between the two methods were so slight that keeping both around did not make sense. Developers who called makeRequest() should be able to switch to using handle() without any further change. [#2123]

Removal of registerNavigationRoute() in favor of createHandlerForURL()

workbox-routing previously supported a method, registerNavigationRoute(), that, under the hood, did two things:

  1. Detecting whether or not a given fetch event had a mode of 'navigate'.
  2. If so, responding to that request using the contents of a previously cached, hardcoded URL, regardless of which URL being navigated to.

(This is a common pattern to use when implementing the App Shell architecture.)

The second step, generating a response by reading from the cache, falls outside of what we envision workbox-routing accomplishing. Instead, we see it as functionality that should be part of workbox-precaching, via a new method, createHandlerForURL(). This new method can work hand-in-hand with the existing NavigationRoute class in workbox-routing to accomplish the same logic. [#2143]

If you're using the navigateFallback option in one of the build tool's generateSW mode, then the switchover will happen automatically, without requiring any change on your part.

If you're using injectManifest mode and your source service worker calls registerNavigationRoute() directly, then you'll have to make a chance to your code to get the equivalent behavior.

Instead of:

import {getCacheKeyForURL} from 'workbox-precaching/getCacheKeyForURL.mjs'
import {registerNavigationRoute} from 'workbox-routing/registerNavigationRoute.mjs'

const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
  whitelist: [...],
  blacklist: [...],
});

You would need to change to:

import {createHandlerForURL} from 'workbox-precaching/createHandlerForURL.mjs'
import {NavigationRoute} from 'workbox-routing/NavigationRoute.mjs'
import {registerRoute} from 'workbox-routing/registerRoute.mjs'

const handler = createHandlerForURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
  whitelist: [...],
  blacklist: [...],
});
registerRoute(navigationRoute);

(You no longer need to call getCacheKeyForURL(), as createHandlerForURL() will take care of that for you.)

In short, this change makes explicit the two steps that registerNavigationRoute() used to implicitly perform.

🐛 What's Fixed?

TypeScript

workbox-routing

  • Pass matchCallback string/number return values through to handlerCallback. [#2134]

workbox-webpack-plugin

  • In InjectManifest mode, using a .ts file as swSrc and omitting swDest will now lead to a compiled service worker that uses the .js extension. [#2117]

  • In GenerateSW mode, using a swDest value that included subdirectories will now work as expected. [#2140]

Thanks

Special thanks to @azizhk and @jaulz for their contributions that went into this release, as well as @derekdowling and @emillundstrm for their issue reports.

Workbox v5.0.0-alpha.1

16 Jul 00:23
Compare
Choose a tag to compare
Pre-release

🎉 What's New?

The latest alpha release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.

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/registerRoute';
import {CacheFirst} from 'workbox-strategies/CacheFirst';
import {Plugin as ExpirationPlugin} from 'workbox-expiration/Plugin';

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.

Note: The only browser-based Workbox package we haven't converted to TypeScript is workbox-sw, which we don't recommend using with bundlers. As mentioned in the v5.0.0-alpha.0 release notes, our build tools are shifting away from a dependence on a CDN. However, if there are strong use-cases for wanting type definitions for workbox-sw, please let us know, and we can re-evaluate.

🐛 What's Fixed?

Build Tools

  • Fixed an incorrect assumption about the location of node_modules, which could lead to a failed generateSW build process. [#2110]
  • Opt-out of auto-discovering a local Babel configuration file, and instead always use the default @babel/preset-env configuration during the generateSW build process. [@2113]

workbox-window

  • Added the isUpdate property to the controlling event, which was documented but not actually implemented. [#2114 ]

Thanks

Special thanks to @kaykayehnn for their bug reports and contributions that went into this release.

Workbox v5.0.0-alpha.0

10 Jul 17:05
Compare
Choose a tag to compare
Pre-release

Overview of Workbox v5

We're happy to announce the first alpha release of Workbox's v5! This release brings a number of significant changes to all of our build tools: workbox-build, workbox-cli, and workbox-webpack-plugin.

🎉 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-alpha.0/workbox-sw.js') and relying on workbox-sw to dynamically pull in the Workbox runtime code that you neeed 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 genereate 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-proceessing 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 entres. (Developers who have files that exist outside of the webpack asset pipeline are encouragede 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 peform extensive post-processing of a precache manifest:

const manifestTransform = (originalManifest, compilation) => {
  // If anything needs to be propogated 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 v4, 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 simplifiede 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 choosen 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.

⚠️ Breaking Changes

A number of workbox-build, workbox-cli, and workbox-webpack-plugin configuration parameters are no longer supported, following the general outlines of the changes described above. For instance, generateSW will always create a local Workbox runtime bundle for you, so the importWorkboxFrom option no longer makes sense.

We are working on updating the documentation to list the full set of supported options for each mode, but for this alpha, we encourage you to rely on the built-in option validation along with manual inspection of the validation logic if there is any uncertainty.

Thank you for your patience as we get everything documented.

workbox-build

  • The generateSWString mode has been removed. We expect the impact of this to be minimal, as it was primarily used internally by workbox-webpack-plugin.

  • The minimum required version of node has been increased to v8.0.0. This also applies to build tools that use workbox-build, like workbox-cli and workbox-webpack-plugin.

workbox-webpack-plugin

  • This plugin requires now requires webpack v4 or higher.

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 v4.3.1

01 May 18:31
Compare
Choose a tag to compare

🐛 What's Fixed?

workbox-broadcast-update

  • Fixed a bug where some private symbols were not being properly exported from workbox-core, which prevented workbox-broadcast-update from notifying on navigation requests. [#2050]