Webpack plugin that generates a service worker using sw-precache that will cache webpack's bundles' emitted assets. You can optionally pass sw-precache configuration options to webpack through this plugin.
var precacheConfig = [["index.html","b438dd9a399341bee7820c896b1300c4"],["service-worker.js","71e3c3e160519240f1d714ad61d7409a"],["static/css/app.bd2003bb312ba33dc80f36cfeeb931ae.css","a9b8a9386022f23e83e6d0fc83bef900"],["static/js/app.b660598ad0bb5398530c.js","d6a9d22ce769776a0515ffc38ecc6b58"],["static/js/manifest.0c1cd46d93b12dcd0191.js","d00c04d18361873062d9c2af01a83ce0"],["static/js/sw.2c267c30ba142151cb06.js","0e45a19da73e5881c38aa9b3508e1fd9"],["static/js/vendor.8651d0609254c0185bf4.js","f3b2998dc57bce369e8ef04d756b2743"]];
var cacheName = 'sw-precache-v3-new-webapp-' + (self.registration ? self.registration.scope : '');
var ignoreUrlParametersMatching = [/^utm_/];
var addDirectoryIndex = function (originalUrl, index) {
var url = new URL(originalUrl);
if (url.pathname.slice(-1) === '/') {
url.pathname += index;
}
return url.toString();
};
var cleanResponse = function (originalResponse) {
// If this is not a redirected response, then we don't have to do anything.
if (!originalResponse.redirected) {
return Promise.resolve(originalResponse);
}
// Firefox 50 and below doesn't support the Response.body stream, so we may
// need to read the entire body to memory as a Blob.
var bodyPromise = 'body' in originalResponse ?
Promise.resolve(originalResponse.body) :
originalResponse.blob();
return bodyPromise.then(function(body) {
// new Response() is happy when passed either a stream or a Blob.
return new Response(body, {
headers: originalResponse.headers,
status: originalResponse.status,
statusText: originalResponse.statusText
});
});
};
var createCacheKey = function (originalUrl, paramName, paramValue,
dontCacheBustUrlsMatching) {
// Create a new URL object to avoid modifying originalUrl.
var url = new URL(originalUrl);
// If dontCacheBustUrlsMatching is not set, or if we don't have a match,
// then add in the extra cache-busting URL parameter.
if (!dontCacheBustUrlsMatching ||
!(url.pathname.match(dontCacheBustUrlsMatching))) {
url.search += (url.search ? '&' : '') +
encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);
}
return url.toString();
};
var isPathWhitelisted = function (whitelist, absoluteUrlString) {
// If the whitelist is empty, then consider all URLs to be whitelisted.
if (whitelist.length === 0) {
return true;
}
// Otherwise compare each path regex to the path of the URL passed in.
var path = (new URL(absoluteUrlString)).pathname;
return whitelist.some(function(whitelistedPathRegex) {
return path.match(whitelistedPathRegex);
});
url.search = url.search.slice(1) // Exclude initial '?'
.split('&') // Split into an array of 'key=value' strings
.map(function(kv) {
return kv.split('='); // Split each 'key=value' string into a [key, value] array
})
.filter(function(kv) {
return ignoreUrlParametersMatching.every(function(ignoredRegex) {
return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.
});
})
.map(function(kv) {
return kv.join('='); // Join each [key, value] array into a 'key=value' string
})
.join('&'); // Join the array of 'key=value' strings into a string with '&' in between each
return url.toString();
};
var hashParamName = '_sw-precache';
var urlsToCacheKeys = new Map(
precacheConfig.map(function(item) {
var relativeUrl = item[0];
var hash = item[1];
var absoluteUrl = new URL(relativeUrl, self.location);
var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);
return [absoluteUrl.toString(), cacheKey];
})
);
function setOfCachedUrls(cache) {
return cache.keys().then(function(requests) {
return requests.map(function(request) {
return request.url;
});
}).then(function(urls) {
return new Set(urls);
});
}
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return setOfCachedUrls(cache).then(function(cachedUrls) {
return Promise.all(
Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {
// If we don't have a key matching url in the cache already, add it.
if (!cachedUrls.has(cacheKey)) {
var request = new Request(cacheKey, {credentials: 'same-origin'});
return fetch(request).then(function(response) {
// Bail out of installation unless we get back a 200 OK for
// every request.
if (!response.ok) {
throw new Error('Request for ' + cacheKey + ' returned a ' +
'response with status ' + response.status);
}
return cleanResponse(response).then(function(responseToCache) {
return cache.put(cacheKey, responseToCache);
});
});
}
})
);
});
}).then(function() {
// Force the SW to transition from installing -> active state
return self.skipWaiting();
})
);
});
self.addEventListener('activate', function(event) {
var setOfExpectedUrls = new Set(urlsToCacheKeys.values());
self.addEventListener('fetch', function(event) {
if (event.request.method === 'GET') {
// Should we call event.respondWith() inside this fetch event handler?
// This needs to be determined synchronously, which will give other fetch
// handlers a chance to handle the request if need be.
var shouldRespond;
// First, remove all the ignored parameters and hash fragment, and see if we
// have that URL in our cache. If so, great! shouldRespond will be true.
var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);
shouldRespond = urlsToCacheKeys.has(url);
// If shouldRespond is false, check again, this time with 'index.html'
// (or whatever the directoryIndex option is set to) at the end.
var directoryIndex = 'index.html';
if (!shouldRespond && directoryIndex) {
url = addDirectoryIndex(url, directoryIndex);
shouldRespond = urlsToCacheKeys.has(url);
}
// If shouldRespond is still false, check to see if this is a navigation
// request, and if so, whether the URL matches navigateFallbackWhitelist.
var navigateFallback = '';
if (!shouldRespond &&
navigateFallback &&
(event.request.mode === 'navigate') &&
isPathWhitelisted([], event.request.url)) {
url = new URL(navigateFallback, self.location).toString();
shouldRespond = urlsToCacheKeys.has(url);
}
// If shouldRespond was set to true at any point, then call
// event.respondWith(), using the appropriate cache key.
if (shouldRespond) {
event.respondWith(
caches.open(cacheName).then(function(cache) {
return cache.match(urlsToCacheKeys.get(url)).then(function(response) {
if (response) {
return response;
}
throw Error('The cached response that was expected is missing.');
});
}).catch(function(e) {
// Fall back to just fetch()ing the request if some unexpected error
// prevented the cached response from being valid.
console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e);
return fetch(event.request);
})
);
}
I'm submitting a support request
My question in general I want to add push listener and so on to service worker, but I am not sure how and where through the example of a template https://github.com/vuetifyjs/pwa/blob/master/template/build/service-worker-prod.js . I assume that it will be done with ImportScripts but is having trouble figuring out.
webpack version: 3.7.1
sw-precache-webpack-plugin version: 0.11.4
Please tell us about your environment: OSX 10.12.6
Browser: Chrome Version 65.0.3325.181 (Official Build) (64-bit)
Current behavior:
Expected/desired behavior:
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem along with your:
var precacheConfig = [["index.html","b438dd9a399341bee7820c896b1300c4"],["service-worker.js","71e3c3e160519240f1d714ad61d7409a"],["static/css/app.bd2003bb312ba33dc80f36cfeeb931ae.css","a9b8a9386022f23e83e6d0fc83bef900"],["static/js/app.b660598ad0bb5398530c.js","d6a9d22ce769776a0515ffc38ecc6b58"],["static/js/manifest.0c1cd46d93b12dcd0191.js","d00c04d18361873062d9c2af01a83ce0"],["static/js/sw.2c267c30ba142151cb06.js","0e45a19da73e5881c38aa9b3508e1fd9"],["static/js/vendor.8651d0609254c0185bf4.js","f3b2998dc57bce369e8ef04d756b2743"]]; var cacheName = 'sw-precache-v3-new-webapp-' + (self.registration ? self.registration.scope : '');
var ignoreUrlParametersMatching = [/^utm_/];
var addDirectoryIndex = function (originalUrl, index) { var url = new URL(originalUrl); if (url.pathname.slice(-1) === '/') { url.pathname += index; } return url.toString(); };
var cleanResponse = function (originalResponse) { // If this is not a redirected response, then we don't have to do anything. if (!originalResponse.redirected) { return Promise.resolve(originalResponse); }
};
var createCacheKey = function (originalUrl, paramName, paramValue, dontCacheBustUrlsMatching) { // Create a new URL object to avoid modifying originalUrl. var url = new URL(originalUrl);
};
var isPathWhitelisted = function (whitelist, absoluteUrlString) { // If the whitelist is empty, then consider all URLs to be whitelisted. if (whitelist.length === 0) { return true; }
};
var stripIgnoredUrlParameters = function (originalUrl, ignoreUrlParametersMatching) { var url = new URL(originalUrl); // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290 url.hash = '';
};
var hashParamName = '_sw-precache'; var urlsToCacheKeys = new Map( precacheConfig.map(function(item) { var relativeUrl = item[0]; var hash = item[1]; var absoluteUrl = new URL(relativeUrl, self.location); var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false); return [absoluteUrl.toString(), cacheKey]; }) );
function setOfCachedUrls(cache) { return cache.keys().then(function(requests) { return requests.map(function(request) { return request.url; }); }).then(function(urls) { return new Set(urls); }); }
self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return setOfCachedUrls(cache).then(function(cachedUrls) { return Promise.all( Array.from(urlsToCacheKeys.values()).map(function(cacheKey) { // If we don't have a key matching url in the cache already, add it. if (!cachedUrls.has(cacheKey)) { var request = new Request(cacheKey, {credentials: 'same-origin'}); return fetch(request).then(function(response) { // Bail out of installation unless we get back a 200 OK for // every request. if (!response.ok) { throw new Error('Request for ' + cacheKey + ' returned a ' + 'response with status ' + response.status); }
); });
self.addEventListener('activate', function(event) { var setOfExpectedUrls = new Set(urlsToCacheKeys.values());
event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.keys().then(function(existingRequests) { return Promise.all( existingRequests.map(function(existingRequest) { if (!setOfExpectedUrls.has(existingRequest.url)) { return cache.delete(existingRequest); } }) ); }); }).then(function() {
); });
self.addEventListener('fetch', function(event) { if (event.request.method === 'GET') { // Should we call event.respondWith() inside this fetch event handler? // This needs to be determined synchronously, which will give other fetch // handlers a chance to handle the request if need be. var shouldRespond;
} });
importScripts("/static/js/sw.2c267c30ba142151cb06.js");
webpackJsonp([2],{
// 167: // (function(module, exports) {
console.log('Injecting from importScripts')
self.addEventListener('push', function(event) { const title = 'Yay a message.' const body = 'We have received a push message.' const icon = '/images/icon-192x192.png' const tag = 'simple-push-demo-notification-tag' const data = { doge: { wow: 'such amaze notification data' } } event.waitUntil( self.registration.showNotification(title, { body: body, icon: icon, tag: tag, data: data }) ) })
self.addEventListener('notificationclick', function(event) { event.notification.close() if (event.action === 'archive') alert('archive your email') else clients.openWindow('/settings') }, false)
/***/ })
},[167]);
// WEBPACK FOOTER // // static/js/sw.2c267c30ba142151cb06.js