Skip to content

Commit

Permalink
Feature/workbox recipes (#2664)
Browse files Browse the repository at this point in the history
* First pass at two recipes

Google Fonts cache and Image cache

* Update ImageCache structure

Aligns with other work, can create multiple if need multiple instead of using .register

* Add OfflineFallback, PageCache, and StaticResourceCache

Rounds out initial set of recipes

* Add sample for usage of recipes

* Rename, fix linting issues

* Rename ts files

* Fix module name

* Include Gulp in scripts

Allows you to use the dependency-installed Gulp to run tasks instead of a global Gulp

* Pull dependencies  from their compiled files

* Add workbox-recipes mjs ignores

* Adding workbox-recipes deps

Co-authored-by: Jeff Posnick <jeffy@google.com>
  • Loading branch information
Snugug and jeffposnick committed Nov 13, 2020
1 parent 57ad215 commit 06e51db
Show file tree
Hide file tree
Showing 18 changed files with 431 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -36,6 +36,7 @@ packages/workbox-google-analytics/**/*.mjs
packages/workbox-navigation-preload/**/*.mjs
packages/workbox-precaching/**/*.mjs
packages/workbox-range-requests/**/*.mjs
packages/workbox-recipes/**/*.mjs
packages/workbox-routing/**/*.mjs
packages/workbox-strategies/**/*.mjs
packages/workbox-streams/**/*.mjs
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -4,7 +4,8 @@
"node": ">=10.0.0"
},
"scripts": {
"version": "git add -A packages"
"version": "git add -A packages",
"gulp": "gulp"
},
"nyc": {
"include": [
Expand Down
1 change: 1 addition & 0 deletions packages/workbox-build/package.json
Expand Up @@ -51,6 +51,7 @@
"workbox-navigation-preload": "^6.0.0-alpha.3",
"workbox-precaching": "^6.0.0-alpha.3",
"workbox-range-requests": "^6.0.0-alpha.3",
"workbox-recipes": "^6.0.0-alpha.3",
"workbox-routing": "^6.0.0-alpha.3",
"workbox-strategies": "^6.0.0-alpha.3",
"workbox-streams": "^6.0.0-alpha.3",
Expand Down
1 change: 1 addition & 0 deletions packages/workbox-recipes/README.md
@@ -0,0 +1 @@
This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-recipes
55 changes: 55 additions & 0 deletions packages/workbox-recipes/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions packages/workbox-recipes/package.json
@@ -0,0 +1,33 @@
{
"name": "workbox-recipes",
"version": "6.0.0-alpha.3",
"license": "MIT",
"author": "Google's Web DevRel Team",
"description": "A service worker helper library to manage common request and caching patterns",
"repository": "googlechrome/workbox",
"bugs": "https://github.com/googlechrome/workbox/issues",
"homepage": "https://github.com/GoogleChrome/workbox",
"keywords": [
"workbox",
"workboxjs",
"service worker",
"sw",
"router",
"routing"
],
"workbox": {
"browserNamespace": "workbox.recipes",
"packageType": "sw"
},
"main": "index.js",
"module": "index.mjs",
"types": "index.d.ts",
"dependencies": {
"workbox-strategies": "^6.0.0-alpha.3",
"workbox-routing": "^6.0.0-alpha.3",
"workbox-cacheable-response": "^6.0.0-alpha.3",
"workbox-expiration": "^6.0.0-alpha.3",
"workbox-core": "^6.0.0-alpha.3",
"workbox-precaching": "^6.0.0-alpha.3"
}
}
2 changes: 2 additions & 0 deletions packages/workbox-recipes/src/_version.ts
@@ -0,0 +1,2 @@
// @ts-ignore
try{self['workbox:recipes:6.0.0-alpha.3']&&_()}catch(e){}
64 changes: 64 additions & 0 deletions packages/workbox-recipes/src/googleFontsCache.ts
@@ -0,0 +1,64 @@
/*
Copyright 2020 Google LLC
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
import {registerRoute} from 'workbox-routing/registerRoute.js';
import {StaleWhileRevalidate} from 'workbox-strategies/StaleWhileRevalidate.js';
import {CacheFirst} from 'workbox-strategies/CacheFirst.js';
import {CacheableResponsePlugin} from 'workbox-cacheable-response/CacheableResponsePlugin.js';
import {ExpirationPlugin} from 'workbox-expiration/ExpirationPlugin.js';

import './_version.js';

export interface GoogleFontCacheOptions {
cachePrefix?: string;
maxAgeSeconds?: number;
maxEntries?: number;
}

/**
* An implementation of the [Google fonts]{@link https://developers.google.com/web/tools/workbox/guides/common-recipes#google_fonts} caching recipe
*
* @memberof module:workbox-recipes
*
* @param {Object} [options]
* @param {string} [options.cachePrefix] Cache prefix for caching stylesheets and webfonts. Defaults to google-fonts
* @param {number} [options.maxAgeSeconds] Maximum age, in seconds, that font entries will be cached for. Defaults to 1 year
* @param {number} [options.maxEntries] Maximum number of fonts that will be cached. Defaults to 30
*/
function googleFontsCache(options: GoogleFontCacheOptions = {}) {
const sheetCacheName = `${options.cachePrefix || 'google-fonts'}-stylesheets`;
const fontCacheName = `${options.cachePrefix || 'google-fonts'}-webfonts`;
const maxAgeSeconds = options.maxAgeSeconds || 60 * 60 * 24 * 365;
const maxEntries = options.maxEntries || 30;

// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
registerRoute(
({ url }) => url.origin === 'https://fonts.googleapis.com',
new StaleWhileRevalidate({
cacheName: sheetCacheName,
})
);

// Cache the underlying font files with a cache-first strategy for 1 year.
registerRoute(
({ url }) => url.origin === 'https://fonts.gstatic.com',
new CacheFirst({
cacheName: fontCacheName,
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200],
}),
new ExpirationPlugin({
maxAgeSeconds,
maxEntries,
}),
],
})
);
}

export { googleFontsCache }
58 changes: 58 additions & 0 deletions packages/workbox-recipes/src/imageCache.ts
@@ -0,0 +1,58 @@
/*
Copyright 2020 Google LLC
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
import {registerRoute} from 'workbox-routing/registerRoute.js';
import {CacheFirst} from 'workbox-strategies/CacheFirst.js';
import {CacheableResponsePlugin} from 'workbox-cacheable-response/CacheableResponsePlugin.js';
import {ExpirationPlugin} from 'workbox-expiration/ExpirationPlugin.js';
import {RouteMatchCallback, RouteMatchCallbackOptions} from 'workbox-core/types.js';

import './_version.js';

export interface ImageCacheOptions {
cacheName?: string;
matchCallback?: RouteMatchCallback;
maxAgeSeconds?: number;
maxEntries?: number;
}

/**
* An implementation of the [image caching recipe]{@link https://developers.google.com/web/tools/workbox/guides/common-recipes#caching_images}
*
* @memberof module:workbox-recipes
*
* @param {Object} [options]
* @param {string} [options.cacheName] Name for cache. Defaults to images
* @param {number} [options.maxAgeSeconds] Maximum age, in seconds, that font entries will be cached for. Defaults to 30 days
* @param {number} [options.maxEntries] Maximum number of images that will be cached. Defaults to 60
*/
function imageCache(options: ImageCacheOptions = {}) {
const defaultMatchCallback = ({request}: RouteMatchCallbackOptions) => request.destination === 'image';

const cacheName = options.cacheName || 'images';
const matchCallback = options.matchCallback || defaultMatchCallback;
const maxAgeSeconds = options.maxAgeSeconds || 30 * 24 * 60 * 60;
const maxEntries = options.maxEntries || 60;

registerRoute(
matchCallback,
new CacheFirst({
cacheName,
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200],
}),
new ExpirationPlugin({
maxEntries,
maxAgeSeconds
}),
],
})
);
}

export { imageCache }
28 changes: 28 additions & 0 deletions packages/workbox-recipes/src/index.ts
@@ -0,0 +1,28 @@
/*
Copyright 2020 Google LLC
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/

import {googleFontsCache} from './googleFontsCache';
import {imageCache} from './imageCache';
import {staticResourceCache} from './staticResourceCache';
import {pageCache} from './pageCache';
import {offlineFallback} from './offlineFallback';

import './_version.js';


/**
* @module workbox-recipes
*/

export {
googleFontsCache,
imageCache,
staticResourceCache,
pageCache,
offlineFallback
};
58 changes: 58 additions & 0 deletions packages/workbox-recipes/src/offlineFallback.ts
@@ -0,0 +1,58 @@
/*
Copyright 2020 Google LLC
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
import {setCatchHandler} from 'workbox-routing/setCatchHandler.js';
import {matchPrecache} from 'workbox-precaching/matchPrecache.js';
import {RouteHandler, RouteHandlerCallbackOptions} from 'workbox-core/types.js';

import './_version.js';

export interface OfflineFallbackOptions {
pageFallback?: string;
imageFallback?: string;
fontFallback?: string;
}

/**
* An implementation of the [comprehensive fallbacks recipe]{@link https://developers.google.com/web/tools/workbox/guides/advanced-recipes#comprehensive_fallbacks}. Be sure to include the fallbacks in your precache injection
*
* @memberof module:workbox-recipes
*
* @param {Object} [options]
* @param {string} [options.pageFallback] Precache name to match for pag fallbacks. Defaults to offline.html
* @param {string} [options.imageFallback] Precache name to match for image fallbacks.
* @param {string} [options.fontFallback] Precache name to match for font fallbacks.
*/
function offlineFallback(options: OfflineFallbackOptions = {}) {
const pageFallback = options.pageFallback || 'offline.html';
const imageFallback = options.imageFallback || false;
const fontFallback = options.fontFallback || false;

const handler: RouteHandler = async (
options: RouteHandlerCallbackOptions
) => {
const dest = options.request.destination;

if (dest === "document") {
return (await matchPrecache(pageFallback)) || Response.error();
}

if (dest === "image" && imageFallback !== false) {
return (await matchPrecache(imageFallback)) || Response.error();
}

if (dest === "font" && fontFallback !== false) {
return (await matchPrecache(fontFallback)) || Response.error();
}

return Response.error();
};

setCatchHandler(handler);
}

export { offlineFallback }
52 changes: 52 additions & 0 deletions packages/workbox-recipes/src/pageCache.ts
@@ -0,0 +1,52 @@
/*
Copyright 2020 Google LLC
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
import {registerRoute} from 'workbox-routing/registerRoute.js';
import {NetworkFirst} from 'workbox-strategies/NetworkFirst.js';
import {CacheableResponsePlugin} from 'workbox-cacheable-response/CacheableResponsePlugin.js';
import {RouteMatchCallback, RouteMatchCallbackOptions} from 'workbox-core/types.js';

import './_version.js';

export interface ImageCacheOptions {
cacheName?: string;
matchCallback?: RouteMatchCallback;
networkTimeoutSeconds?: number;
}

/**
* An implementation of a page caching recipe with a network timeout
*
* @memberof module:workbox-recipes
*
* @param {Object} [options]
* @param {string} [options.cacheName] Name for cache. Defaults to pages
* @param {RouteMatchCallback} [options.matchCallback] Workbox callback function to call to match to. Defaults to request.mode === 'navigate';
* @param {number} [options.networkTimoutSeconds] Maximum amount of time, in seconds, to wait on the network before falling back to cache. Defaults to 3
*/
function pageCache(options: ImageCacheOptions = {}) {
const defaultMatchCallback = ({request}: RouteMatchCallbackOptions) => request.mode === 'navigate';

const cacheName = options.cacheName || 'pages';
const matchCallback = options.matchCallback || defaultMatchCallback;
const networkTimeoutSeconds = options.networkTimeoutSeconds || 3;

registerRoute(
matchCallback,
new NetworkFirst({
networkTimeoutSeconds,
cacheName,
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200],
}),
],
})
);
}

export { pageCache }

0 comments on commit 06e51db

Please sign in to comment.