### Install and Activate PrecacheController Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-precaching/static/precache.html Use these event listeners to manage the precaching lifecycle by adding files to the controller and invoking install or activate methods. ```javascript self.registration = { scope: 'injected-scope', }; let lastInstallValues = []; let flipFile = 'example-a.html'; const installBtn = document.querySelector('.js-index-install'); installBtn.addEventListener('click', (event) => { const precacheController = new workbox.precaching.PrecacheController(); lastInstallValues = [ './project/index.html', `./project/${flipFile}`, {url: './project/example.html'}, {url: './project/example-2.html', revision: '123'}, {url: './project/example-timestamp.html', revision: Date.now()}, ]; precacheController.addToCacheList(lastInstallValues); precacheController.install(event); if (flipFile === 'example-a.html') { flipFile = 'example-b.html'; } else { flipFile = 'example-a.html'; } }); const activateBtn = document.querySelector('.js-index-activate'); activateBtn.addEventListener('click', (event) => { const precacheController = new workbox.precaching.PrecacheController(); precacheController.addToCacheList(lastInstallValues); precacheController.activate(event); }); ``` -------------------------------- ### Build and Test Workbox Locally Source: https://github.com/googlechrome/workbox/blob/v7/CONTRIBUTING.md Commands to install dependencies, build the project, and execute the full test suite. ```sh $ npm ci $ npm run gulp build $ npm run gulp test ``` -------------------------------- ### Install and Interact with Service Worker Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-core/index.html This JavaScript code snippet handles the installation of a service worker and sets up event listeners for buttons to trigger logging and cache name display. Ensure the service worker file ('/sw.js') is correctly configured. ```javascript const installSWBtn = document.querySelector('.install-sw'); const showLogsBtn = document.querySelector('.show-logs'); const cacheNamesBtn = document.querySelector('.show-cache-names'); installSWBtn.addEventListener('click', () => { console.log('Installing service worker'); navigator.serviceWorker.register('/sw.js').then((reg) => { showLogsBtn.addEventListener('click', () => { const message = { command: 'printLogs', }; reg.active.postMessage(message); }); cacheNamesBtn.addEventListener('click', () => { const message = { command: 'printCacheNames', }; reg.active.postMessage(message); }); }); }); ``` -------------------------------- ### Launch Browser Test Server Source: https://github.com/googlechrome/workbox/blob/v7/CONTRIBUTING.md Starts the local test server for browser-based code, accessible at http://localhost:3004/. ```sh npm run gulp test_server ``` -------------------------------- ### Start Local Test Server Source: https://github.com/googlechrome/workbox/wiki/Testing Launch a local test server to manually inspect endpoints and behavior in a browser outside of a webdriver controller. ```shell gulp test-server ``` -------------------------------- ### Install Service Worker Button Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-sw/index.html This JavaScript code registers a service worker when a button is clicked. Ensure the button with the class 'install-sw' exists in your HTML. ```javascript const installSWBtn = document.querySelector('.install-sw'); installSWBtn.addEventListener('click', () => { navigator.serviceWorker.register('./sw.js'); }); ``` -------------------------------- ### Define named webpack chunks Source: https://github.com/googlechrome/workbox/wiki/webpack-Plugin-Info Example of a webpack configuration defining multiple entry points, resulting in named chunks. ```js const webpackConfig = { entry: { chunk1: './path/to/my/entry/file1.js', chunk2: './path/to/my/entry/file2.js' }, // etc. } ``` -------------------------------- ### Initialize Google Analytics and Service Worker Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-google-analytics/index.html Standard Google Analytics initialization script combined with service worker registration and event listener setup for tracking clicks. ```javascript (function (i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; (i[r] = i[r] || function () { (i[r].q = i[r].q || []).push(arguments); }), (i[r].l = 1 * new Date()); (a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]); a.async = 1; a.src = g; m.parentNode.insertBefore(a, m); })( window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga', ); ga('create', 'UA-77119321-5', 'auto'); const analyticsCallBtn = document.querySelector('.make-analytics-call'); navigator.serviceWorker.register('./sw.js').then((reg) => { analyticsCallBtn.addEventListener('click', () => { ga('send', 'pageview'); }); }); ``` -------------------------------- ### Define an anonymous webpack chunk Source: https://github.com/googlechrome/workbox/wiki/webpack-Plugin-Info Example of a basic webpack configuration using a single entry point, resulting in an anonymous chunk. ```js const webpackConfig = { entry: './path/to/my/entry/file.js', // etc. } ``` -------------------------------- ### Register Service Worker and Inspect Cache Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-build/static/example-project-1/index.html Registers a service worker from a URL parameter, waits for installation, and logs cache entries to a global test result object. ```javascript // Helper function which returns a promise which resolves once the service worker registration // is past the "installing" state. function waitUntilInstalled(registration) { return new Promise(function (resolve, reject) { if (registration.installing) { // If the current registration represents the "installing" service worker, then wait // until the installation step (during which the resources are pre-fetched) completes // to display the file list. registration.installing.addEventListener('statechange', function (e) { if (e.target.state === 'installed') { resolve(); } else if (e.target.state === 'redundant') { reject(); } }); } else { // Otherwise, if this isn't the "installing" service worker, then installation must have been // completed during a previous visit to this page, and the resources are already pre-fetched. // So we can show the list of files right away. resolve(); } }); } const queryString = location.search.substring(1); const keyValues = queryString.split('&'); const searchParams = {}; keyValues.forEach((keyValue) => { const split = keyValue.split('='); if (split[1].indexOf('/') === split[1].length - 1) { split[1] = split[1].substring(0, split[1].length - 1); } searchParams[split[0]] = decodeURIComponent(split[1]); }); navigator.serviceWorker .register(searchParams.sw) .then((registration) => { return waitUntilInstalled(registration); }) .then(() => { return window.caches .keys() .then((keys) => { return window.caches.open(keys[0]); }) .then((cache) => { return cache.keys(); }); }) .then((entries) => { window.__testresult = { entries: entries.map((entry) => { return entry.url; }), }; }) .catch((err) => { document.body.style.color = 'red'; document.body.innerHTML = `
${err.stack}`; console.error(err.message); console.error(err.stack); // This is just to help with local development so we know there is an error setTimeout(() => { window.__testresult = { error: err, }; }, 5 * 1000); });
```
--------------------------------
### Initialize workbox-expiration demo logic
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-expiration/index.html
Sets up service worker registration, entry queue management, and event listeners for cache expiration controls.
```javascript
const expireBtn = document.querySelector('.expire'); const TIMEOUT_IN_SECS = 30; const MAX_ENTRIES = 3; var entryQueue = []; const setupTimeout = (btnElement, textElement) => { textElement.textContent = `${btnElement.__workbox_timeoutCount}s`; btnElement.__workbox_timeoutId = setTimeout(() => { // TODO: FIX THIS TO TAKE FIRST ELEMENT OF CLASS LIST AND CHECK AGAIN ENTRY STACK if (entryQueue.includes(btnElement.classList[0])) { btnElement.__workbox_timeoutCount -= 1; if (btnElement.__workbox_timeoutCount > 0) { setupTimeout(btnElement, textElement); } else { textElement.textContent = `Expired (Too Old)`; } } else { textElement.textContent = `Expired (Too Many)`; } }, 1000); }; window.addEventListener('load', () => { navigator.serviceWorker.register('./sw.js').then((reg) => { for (let i = 0; i < 5; i++) { const entryBtn = document.querySelector(`.entry-${i + 1}`); const expireText = document.querySelector(`.entry-expire-${i + 1}`); entryBtn.addEventListener('click', () => { const message = { command: 'update-entry', id: i + 1, }; var arrayEntry = `entry-${i + 1}`; //If we refresh an entry that has already been added and is not expired //we reorder it to the front of the queue if (entryQueue.includes(arrayEntry)) { entryQueue.splice(entryQueue.indexOf(arrayEntry), 1); } entryQueue.push(`entry-${i + 1}`); if (entryQueue.length >= 4) { entryQueue = entryQueue.slice(MAX_ENTRIES * -1); } reg.active.postMessage(message); if (entryBtn.__workbox_timeoutId) { clearTimeout(entryBtn.__workbox_timeoutId); } entryBtn.__workbox_timeoutCount = TIMEOUT_IN_SECS; setupTimeout(entryBtn, expireText); }); } expireBtn.addEventListener('click', () => { const message = { command: 'expire-entries', }; reg.active.postMessage(message); }); }); });
```
--------------------------------
### Run All Tests
Source: https://github.com/googlechrome/workbox/wiki/Testing
Execute all tests across all Workbox packages. Ensure you are in the root directory of the project.
```shell
gulp test
```
--------------------------------
### Package Directory Structure
Source: https://github.com/googlechrome/workbox/wiki/ES2015-Modules-&-Browser-Bundles
Standard directory layout for a Workbox package.
```text
workbox-example/
package.json
README.md
index.mjs
_private.mjs
FileName1.mjs
exampleDirectory/
FileName2.mjs
```
--------------------------------
### CSS Styles for Streams Demo
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-streams/index.html
Basic styling for the demo page layout.
```css
body { margin-left: 5%; font-family: 'Open Sans', sans-serif; } ol { padding-left: 20px; } li { margin-bottom: 5px; } button { margin: 20px 0; font-weight: bold; }
```
--------------------------------
### Register and Communicate with a Service Worker
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-window/index.html
Initializes a Workbox instance, registers a service worker, and sets up event listeners for lifecycle events. Requires the service worker file to be accessible at the specified path.
```javascript
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/5.0.0-beta.1/workbox-window.prod.mjs'; if ('serviceWorker' in navigator) { const wb = new Workbox('/sw.js'); wb.addEventListener('activated', (event) => { // `event.isUpdate` will be true if another version of the service // worker was controlling the page when this version was registered. if (!event.isUpdate) { console.log('Service worker activated for the first time!'); // If your service worker is configured to precache assets, those // assets should all be available now. } }); wb.addEventListener('waiting', (event) => { console.log( `A new service worker has installed, but it can't activate` + `until all tabs running the current version have fully unloaded.`, ); }); // Register the service worker after event listeners have been added. wb.register(); const message = async () => { const swVersion = await wb.messageSW({type: 'GET_VERSION'}); console.log('Service Worker version:', swVersion); }; message(); }
```
--------------------------------
### Run Tests for a Specific Package
Source: https://github.com/googlechrome/workbox/wiki/Testing
To run tests for a particular Workbox package, use the `--package` flag followed by the package name.
```shell
gulp test --package="workbox-something-something"
```
--------------------------------
### Run Automated Browser Integration Tests
Source: https://github.com/googlechrome/workbox/blob/v7/CONTRIBUTING.md
Executes the browser-based test suite across all supported browsers.
```sh
npm run gulp test_integration
```
--------------------------------
### Implement plugins via composition
Source: https://github.com/googlechrome/workbox/wiki/Styleguide
Plugins should use composition rather than extending the standalone class to prevent method name collisions.
```js
class SomeClassPlugin {
constructor(arg1, arg2) {
this._someInstance = new SomeClass(arg1, arg2);
}
...
}
```
```js
class SomeClassPlugin extends SomeClass {
...
}
```
--------------------------------
### Register Workbox and Lifecycle Helpers
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-window/static/index.html
Exposes the Workbox class to the window object and provides a helper to wait for service worker activation and control.
```javascript
import {Workbox} from '/__WORKBOX/buildFile/workbox-window'; // Expose on the global object so it can be referenced by webdriver. window.Workbox = Workbox; // Returns a promise that resolves when both the activated and controlling // events have fired on the Workbox object. window.activatedAndControlling = (wb) => { const activatedPromise = new Promise((resolve) => { wb.addEventListener('activated', () => resolve()); }); const controllingPromise = new Promise((resolve) => { wb.addEventListener('controlling', () => resolve()); }); return Promise.all([activatedPromise, controllingPromise]); };
```
--------------------------------
### Register Service Worker and Handle Clicks
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-strategies/index.html
This script registers a service worker and sets up event listeners for buttons that trigger different network request strategies. Ensure a service worker file named 'sw.js' is present in the same directory.
```javascript
const cacheOnlyEmpty = document.querySelector('.cache-only-empty-cache');
const cacheOnlyPopulated = document.querySelector( '.cache-only-populated-cache', );
const cacheFirst = document.querySelector('.cache-first');
const networkOnly = document.querySelector('.network-only');
const networkFirstValid = document.querySelector('.network-first-valid');
const networkFirstFailing = document.querySelector( '.network-first-failing', );
const staleWhileRevalidate = document.querySelector( '.stale-while-revalidate', );
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js').then(() => {
cacheOnlyEmpty.addEventListener('click', () => {
fetch('cache-only-empty-cache.txt').catch(() => {});
});
cacheOnlyPopulated.addEventListener('click', () => {
fetch('cache-only-populated-cache').then((response) => {
return response.text();
});
});
cacheFirst.addEventListener('click', () => {
fetch('cache-first.txt').then((response) => {
return response.text();
});
});
networkOnly.addEventListener('click', () => {
fetch('network-only.txt').then((response) => {
return response.text();
});
});
networkFirstValid.addEventListener('click', () => {
fetch('network-first.txt').then((response) => {
return response.text();
});
});
networkFirstFailing.addEventListener('click', () => {
fetch('network-first-404.txt').catch(() => {});
});
staleWhileRevalidate.addEventListener('click', () => {
fetch('stale-while-revalidate.txt').then((response) => {
return response.text();
});
});
});
});
```
--------------------------------
### Run Integration Tests
Source: https://github.com/googlechrome/workbox/wiki/Testing
Execute integration tests which have full access to browser and service worker APIs.
```shell
gulp test-integration
```
--------------------------------
### Implement Range Request Logic
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-range-requests/index.html
Registers a service worker and sets up a click listener to fetch a specific byte range from a cached response.
```javascript
const makeRequestBtn = document.querySelector('.make-range-request'); caches .open('range-requests-demo') .then((cache) => cache.put('/range-request-example', new Response('hello, world.')), ); navigator.serviceWorker.register('./sw.js').then(() => { makeRequestBtn.addEventListener('click', () => { fetch( new Request('/range-request-example', { headers: { Range: `bytes=1-4`, }, }), ) .then((response) => response.text()) .then((responseText) => { console.log(`Received response: '${responseText}'`); }); }); });
```
--------------------------------
### Register Service Worker and Fetch with Custom Headers
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-cacheable-response/index.html
This script registers a service worker and sets up event listeners for buttons that trigger fetch requests. It demonstrates sending custom headers ('X-Is-Cacheable') to influence caching behavior.
```javascript
const withGoodHeaderBtn = document.querySelector('.with-good-header');
const withBadHeaderBtn = document.querySelector('.with-bad-header');
const withoutHeaderBtn = document.querySelector('.without-header');
const DEMO_REQUEST_URL = '/api/is-response-cacheable';
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js').then(() => {
withGoodHeaderBtn.addEventListener('click', () => {
fetch(DEMO_REQUEST_URL, {
headers: {
'X-Is-Cacheable': true,
},
});
});
withBadHeaderBtn.addEventListener('click', () => {
fetch(DEMO_REQUEST_URL, {
headers: {
'X-Is-Cacheable': false,
},
});
});
withoutHeaderBtn.addEventListener('click', () => {
fetch(DEMO_REQUEST_URL);
});
});
});
```
--------------------------------
### Log Various Data Types with Workbox Logger
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-core/static/logger.html
This snippet demonstrates logging different data types like strings, objects, arrays, and booleans using `logger.log()`, `logger.debug()`, `logger.warn()`, and `logger.error()`. Ensure your browser's developer tools are set to display all log levels, as debug logs might be hidden by default.
```javascript
self.registration = {
scope: 'inject-scope',
};
const logger = workbox.core._private.logger;
const SIMPLE_OUTPUT_TESTS = [
// String
'Hello from demo.',
// Objects
{
foo: {
bar: {
baz: 'Yo.',
},
},
},
['Example of an Array', {with: 'objects'}, true, false],
true,
false,
1234,
];
const MULTIPLE_ARGS_OUTPUT_TESTS = [
['Testing', 'multiple', 'strings'],
['Testing', {mixed: 'items'}, 'in', ['a', 'log']],
[{this: 'is'}, 'different', 'cos', {strings: 'are'}, 'not first'],
];
const allLogBtns = [
{
className: '.js-log',
funcName: 'log',
},
{
className: '.js-debug',
funcName: 'debug',
},
{
className: '.js-warn',
funcName: 'warn',
},
{
className: '.js-error',
funcName: 'error',
},
];
allLogBtns.forEach((logBtnDetails) => {
const btnElement = document.querySelector(logBtnDetails.className);
btnElement.addEventListener('click', () => {
SIMPLE_OUTPUT_TESTS.forEach((output) => {
logger[logBtnDetails.funcName](output);
});
MULTIPLE_ARGS_OUTPUT_TESTS.forEach((output) => {
logger[logBtnDetails.funcName](...output);
});
console.log('\n\n');
});
});
```
--------------------------------
### Run Node Tests
Source: https://github.com/googlechrome/workbox/wiki/Testing
Execute tests that run in a Node.js environment, often utilizing mocked browser APIs.
```shell
gulp test-node
```
--------------------------------
### Cross-Module Imports
Source: https://github.com/googlechrome/workbox/wiki/ES2015-Modules-&-Browser-Bundles
Referencing code from other Workbox modules using direct file paths.
```javascript
// Inside of a file in workbox-routing
import {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';
throw new WorkboxError('error-code');
```
--------------------------------
### Add Unrevisioned Assets with PrecacheController
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-precaching/static/addToCacheList.html
Use this method to add specific URLs to the cache list dynamically. Ensure the PrecacheController is instantiated before calling this method.
```javascript
const precacheController = new workbox.precaching.PrecacheController(); const indexStringBtn = document.querySelector('.js-index-unrevisioned'); indexStringBtn.addEventListener('click', () => { precacheController.addToCacheList([ '/index.html', {url: '/example.html'}, ]); });
```
--------------------------------
### Run Node-based Tooling Tests
Source: https://github.com/googlechrome/workbox/blob/v7/CONTRIBUTING.md
Executes the test suite specifically for node-based tooling packages.
```sh
npm run gulp test_node
```
--------------------------------
### Workbox Streams Module
Source: https://github.com/googlechrome/workbox/blob/v7/packages/workbox-streams/README.md
Reference documentation for the workbox-streams module.
```APIDOC
## Workbox Streams Module
### Description
The workbox-streams module provides utilities for creating and managing streams within a service worker, enabling the streaming of responses to the browser.
### Reference
For detailed API documentation, class definitions, and method signatures, please refer to the official documentation at: https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-streams
```
--------------------------------
### Derive asset to chunk mapping
Source: https://github.com/googlechrome/workbox/wiki/webpack-Plugin-Info
Logic used to build a mapping of files to their associated chunk names and hashes by iterating through compilation chunks.
```js
const mapping = {};
for (const chunk of chunks) {
for (const file of chunk.files) {
mapping[file] = {
chunkName: chunk.name,
hash: chunk.renderedHash,
};
}
}
```
--------------------------------
### Workbox Browser Namespace Metadata
Source: https://github.com/googlechrome/workbox/wiki/Adding-a-new-package
This JSON snippet shows the required metadata in a new package's package.json for Workbox. Ensure 'browserNamespace' matches the mapping in WorkboxSW.mjs.
```json
{
"workbox": {
"browserNamespace": "workbox.somethingNew",
"packageType": "browser"
}
}
```
--------------------------------
### Package Import Restrictions
Source: https://github.com/googlechrome/workbox/wiki/ES2015-Modules-&-Browser-Bundles
Direct file imports are required to prevent unnecessary bloat in builds.
```javascript
// Bad
import {bar} from 'workbox-foo';
```
```javascript
// Good
import {bar} from 'workbox-foo/bar.mjs';
```
--------------------------------
### Conditional Module Exports
Source: https://github.com/googlechrome/workbox/wiki/ES2015-Modules-&-Browser-Bundles
Selecting different exports based on the build environment to optimize bundle size.
```javascript
const ourExport = (process.env.NODE_ENV === 'production') ? slimExport : largeExport;
export default ourExport
```
--------------------------------
### Register Service Worker and Fetch Request
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-background-sync-demo/index.html
Registers the service worker and attaches a click event listener to trigger a fetch request.
```javascript
document.querySelector('.fetch').addEventListener('click', () => { fetch('example.txt'); }); navigator.serviceWorker.register('./sw.js');
```
--------------------------------
### Use options object for optional arguments
Source: https://github.com/googlechrome/workbox/wiki/Styleguide
Required fields should be positional, but an options object is preferred when expecting a wide variety of optional values.
```js
new Route(matchFunc, handleFunc, options);
```
--------------------------------
### Register Service Worker and Handle Stream Request
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-streams/index.html
Registers the service worker and sets up an event listener to append an iframe that triggers a streamed response.
```javascript
const makeRequestBtn = document.querySelector('.make-streams-request'); navigator.serviceWorker.register('./sw.js').then(() => { makeRequestBtn.addEventListener('click', () => { const iframe = document.createElement('iframe'); // This URL will be handled by the service worker. iframe.src = 'iframe'; document.querySelector('#iframes').appendChild(iframe); }); });
```
--------------------------------
### Register Service Worker with Workbox CDN
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-sw/static/index.html
Use this JavaScript snippet to register a service worker that loads Workbox from a CDN. Ensure 'sw.js' is correctly configured.
```javascript
navigator.serviceWorker.register('sw.js');
```
--------------------------------
### Dead Code Elimination with NODE_ENV
Source: https://github.com/googlechrome/workbox/wiki/ES2015-Modules-&-Browser-Bundles
Using environment variables to allow Rollup to strip development-only code from production bundles.
```javascript
// Our source code looks like this
if (process.env.NODE_ENV !== 'production') {
console.log(`Hey this is super helpful but also increases file size.`);
} else {
console.log(`Hi.`);
}
// For dev builds, the above code will be outputted as
{
console.log(`Hey this is super helpful but also increases file size.`);
}
// For prod builds, the output is
{
console.log(`Hi.`);
}
```
--------------------------------
### Initialize Chai Expectation
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-window/static/index.html
Exposes the Chai expect function to the global scope for use in test assertions.
```javascript
self.expect = self.chai.expect;
```
--------------------------------
### Create Collapsible Log Groups with Workbox Logger
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-core/static/logger.html
This snippet demonstrates how to use `logger.groupCollapsed()` to create collapsible log groups, allowing for better organization of related log messages. Nested groups are also supported. Use `logger.groupEnd()` to close the current group.
```javascript
const groupBtn = document.querySelector('.js-group');
groupBtn.addEventListener('click', () => {
logger.groupCollapsed(`I'm the title for logger.groupCollapsed()`);
const innerLog = [`I'm inside the group`, {cool: true}];
logger.debug(...innerLog);
logger.log(...innerLog);
logger.warn(...innerLog);
logger.error(...innerLog);
logger.groupCollapsed(
`I'm the title for a nested logger.groupCollapsed() call`,
);
const nestedLog = [`I'm doubly inside`, {superCool: true}];
logger.debug(...nestedLog);
logger.log(...nestedLog);
logger.warn(...nestedLog);
logger.error(...nestedLog);
logger.groupEnd();
logger.groupEnd();
console.log('\n\n');
});
```
--------------------------------
### Use destructuring for callbacks
Source: https://github.com/googlechrome/workbox/wiki/Styleguide
Callbacks should use destructuring to allow developers to select only the elements they need.
```js
plugin.cacheDidUpdate({cacheName, request, cachedResponse, newResponse});
```
```js
router.cacheDidUpdate(cacheName, request, cachesRedponse, newResponse);
```
```js
plugin.cacheDidUpdate({cachedResponse})
```
```js
{
cacheDidUpdate: (values) => console.log(values),
}
```
--------------------------------
### Log isURLExpired() Performance
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-expiration/static/isURLExpired.html
This snippet logs the time taken by `isURLExpired()` and its result. It requires Workbox's expiration module and sets up a cache with a maximum age of 2 seconds.
```javascript
self.registration = { scope: 'inject-scope', }; const CacheExpiration = workbox.expiration.CacheExpiration;
const expirationManager = new CacheExpiration('cache-name', { maxAgeSeconds: 2, });
expirationManager.updateTimestamp('/', Date.now());
const test = async () => {
const t0 = performance.now();
const expired = await expirationManager.isURLExpired('/');
const t1 = performance.now();
console.log(
`Call to doSomething took "${t1 - t0}" milliseconds.`,
expired,
);
};
test();
setTimeout(test, 2000);
```
--------------------------------
### Use positional arguments for method calls
Source: https://github.com/googlechrome/workbox/wiki/Styleguide
Methods called against a Workbox module should use positional arguments to avoid verbosity.
```js
router.registerRoutes([...]);
```
```js
router.registerRoutes({routes: [....]});
```
--------------------------------
### precache.addToCacheList()
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-precaching/static/addToCacheList.html
Adds unrevisioned assets to the PrecacheController's cache list.
```APIDOC
## precache.addToCacheList()
### Description
Adds a list of unrevisioned assets to the PrecacheController instance for caching.
### Parameters
- **entries** (Array) - Required - An array of strings or objects representing the URLs to be cached.
### Request Example
```javascript
precacheController.addToCacheList([
'/index.html',
{url: '/example.html'}
]);
```
```
--------------------------------
### Register Service Worker
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-routing/index.html
Attaches a click event listener to a button to register the service worker file.
```javascript
const firstBtn = document.querySelector('.install-sw'); firstBtn.addEventListener('click', () => { navigator.serviceWorker.register('./sw.js'); });
```
--------------------------------
### Configure Google Analytics and Service Worker Messaging
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-google-analytics/static/basic-example/index.html
Initializes the dataLayer for Google Analytics and defines a helper function to communicate with the service worker via MessageChannel.
```javascript
window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-12345-1', {send_page_view: false}); const messageSW = (data) => { return new Promise((resolve) => { var messageChannel = new MessageChannel(); messageChannel.port1.onmessage = (evt) => resolve(evt.data); navigator.serviceWorker.controller.postMessage(data, [ messageChannel.port2, ]); }); };
```
--------------------------------
### Trigger Broadcast Update
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-broadcast-update-demo/index.html
This JavaScript code registers a service worker and sets up an event listener to post a message to it when a button is clicked. It also listens for messages back from the service worker and logs them to the console. Ensure the service worker ('sw.js') is in the same directory.
```javascript
const triggerBroadcast = document.querySelector('.trigger-broadcast');
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js').then((reg) => {
triggerBroadcast.addEventListener('click', () => {
const message = {
command: 'trigger-broadcast',
};
reg.active.postMessage(message);
});
navigator.serviceWorker.addEventListener('message', (event) => {
console.log("Received a message from workbox-broadcast-update.");
console.log(event.data);
});
});
});
```
--------------------------------
### Identify known hashes from asset metadata
Source: https://github.com/googlechrome/workbox/wiki/webpack-Plugin-Info
Extracts unique hashes from asset metadata to build a set of known identifiers for comparison.
```js
function getKnownHashesFromAssets(assetMetadata) {
const knownHashes = new Set();
for (const metadata of Object.values(assetMetadata)) {
knownHashes.add(metadata.hash);
}
return knownHashes;
}
const knownHashes = [
compilation.hash,
compilation.fullHash,
...getKnownHashesFromAssets(filteredAssetMetadata),
].filter((hash) => !!hash);
```
--------------------------------
### Register Service Worker and Handle Messages
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-broadcast-update/static/index.html
Manually register your service worker script and set up a listener to capture messages sent from it. Ensure the service worker is registered before attempting to send messages.
```javascript
window.__messages = [];
navigator.serviceWorker.addEventListener('message', (event) => {
window.__messages.push(event.data);
});
```
--------------------------------
### Manage Service Worker Requests and Events
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-google-analytics/static/basic-example/index.html
Handles non-GA requests, sync event dispatching, offline simulation, and request logging.
```javascript
document.getElementById('send-non-ga-request').onclick = () => { fetch('https://httpbin.org/get'); }; document.getElementById('dispatch-sync-event').onclick = () => { messageSW({action: 'dispatch-sync-event'}); }; document.getElementById('simulate-offline').onclick = (evt) => { messageSW({ action: 'simulate-offline', value: evt.target.checked, }); }; document.getElementById('clear-spied-requests').onclick = (evt) => { messageSW({action: 'clear-spied-requests'}); }; document.getElementById('log-spied-requests').onclick = async (evt) => { const requests = await messageSW({action: 'get-spied-requests'}); console.log(requests); };
```
--------------------------------
### Register Service Worker
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-navigation-preload/index.html
Registers the service worker file to enable navigation preload functionality.
```javascript
window.addEventListener('load', () => { navigator.serviceWorker.register('./sw.js'); });
```
--------------------------------
### Register and Unregister Service Workers
Source: https://github.com/googlechrome/workbox/blob/v7/demos/src/workbox-precaching/index.html
Handles service worker lifecycle events triggered by button clicks to demonstrate precaching updates.
```javascript
const firstBtn = document.querySelector('.install-sw-1'); const secondBtn = document.querySelector('.install-sw-2'); firstBtn.addEventListener('click', () => { navigator.serviceWorker.register('./sw-1.js'); }); secondBtn.addEventListener('click', () => { navigator.serviceWorker .getRegistration() .then((reg) => { return reg.unregister(); }) .then(() => { navigator.serviceWorker.register('./sw-2.js'); }); });
```
--------------------------------
### Trigger Google Analytics Events
Source: https://github.com/googlechrome/workbox/blob/v7/test/workbox-google-analytics/static/basic-example/index.html
Sends GA events using either image pixel or beacon transport types.
```javascript
document.getElementById('send-ga-pixel').onclick = () => { gtag('event', 'pixel', { transport_type: 'image', }); }; document.getElementById('send-ga-beacon').onclick = () => { gtag('event', 'beacon', { transport_type: 'beacon', }); };
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.