Skip to content
This repository has been archived by the owner on Sep 25, 2023. It is now read-only.

Commit

Permalink
service worker
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonxiang committed May 23, 2017
1 parent f8a338a commit 7be2ce0
Show file tree
Hide file tree
Showing 11 changed files with 292 additions and 7 deletions.
11 changes: 11 additions & 0 deletions build/webpack.prod.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
var SWPrecachePlugin = require('sw-precache-webpack-plugin')

var env = config.build.env

Expand Down Expand Up @@ -117,4 +118,14 @@ if (config.build.bundleAnalyzerReport) {
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

webpackConfig.plugins.push(
// auto generate service worker
new SWPrecachePlugin({
cacheId: 'vue-hn',
filename: 'service-worker.js',
dontCacheBustUrlsMatching: /./,
staticFileGlobsIgnorePatterns: [/index\.html$/, /\.map$/]
})
)

module.exports = webpackConfig
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"sw-precache-webpack-plugin": "^0.9.2",
"url-loader": "^0.5.8",
"vue-loader": "^11.3.4",
"vue-style-loader": "^2.0.5",
Expand Down
5 changes: 5 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,8 @@ new Vue({
// window.addEventListener("resize", setFont, false)
// setFont();
// }

// service worker
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
}
2 changes: 1 addition & 1 deletion www/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><title></title><meta name=format-detection content="telephone=no"><meta name=format-detection content="email=no"><meta name=apple-mobile-web-app-capable content=yes><meta name=apple-mobile-web-app-status-bar-style content=black><link href=static/css/app.43f3598378dc29afd295289edca29048.css rel=stylesheet></head><body ontouchstart><div id=app></div><script type=text/javascript src=static/js/manifest.515c5f4f7a676a8206dd.js></script><script type=text/javascript src=static/js/vendor.f6377a11a892075cc9be.js></script><script type=text/javascript src=static/js/app.ee9c8e5353798c95b13f.js></script></body></html>
<!DOCTYPE html><html><head><title></title><meta name=format-detection content="telephone=no"><meta name=format-detection content="email=no"><meta name=apple-mobile-web-app-capable content=yes><meta name=apple-mobile-web-app-status-bar-style content=black><link href=./static/css/app.43f3598378dc29afd295289edca29048.css rel=stylesheet></head><body ontouchstart><div id=app></div><script type=text/javascript src=./static/js/manifest.3c89dab460961facc5de.js></script><script type=text/javascript src=./static/js/vendor.f6377a11a892075cc9be.js></script><script type=text/javascript src=./static/js/app.cb9eb7853df1efe63c95.js></script></body></html>
268 changes: 268 additions & 0 deletions www/service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/**
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!
// This file should be overwritten as part of your build process.
// If you need to extend the behavior of the generated service worker, the best approach is to write
// additional code and include it using the importScripts option:
// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring
//
// Alternatively, it's possible to make changes to the underlying template file and then use that as the
// new base for generating output, via the templateFilePath option:
// https://github.com/GoogleChrome/sw-precache#templatefilepath-string
//
// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any
// changes made to this original template file with your modified copy.

// This generated service worker JavaScript will precache your site's resources.
// The code needs to be saved in a .js file at the top-level of your site, and registered
// from your pages in order to be used. See
// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js
// for an example of how you can register this script and handle various service worker events.

/* eslint-env worker, serviceworker */
/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */
'use strict';

var precacheConfig = [["./static/blog.json","a1c0284232f6565df6cbbdd794b2c3f2"],["./static/css/app.43f3598378dc29afd295289edca29048.css","cdb7a1d4baa1387318ed59fb687bfe4b"],["./static/img/qrcode.4c602f0.jpg","4c602f01a62e56e4851fa9b2b47e37b8"],["./static/js/0.ac4df46b5f5b6919a7d3.js","c50df4a27e3f8d621fbe087230110224"],["./static/js/1.9113d8d7d82b4c7e3db7.js","e891879c40c87a3f5c49fb96135957d6"],["./static/js/2.66a01449a58fc76097cc.js","71b4eda9d074fe394b4394839241e929"],["./static/js/3.9701290b11837c057258.js","4cb588ef08748362e528a857beb4db8d"],["./static/js/4.e3c67b7be5379da55455.js","fb7765c0a9cb8749e64d879e6588e379"],["./static/js/5.c34a32d098f119aa383f.js","d5fff229096e0f60c224a21f1de20358"],["./static/js/6.449ae9303c55bf45325f.js","af32a3f07e1cdb84c5feea4470bf13a2"],["./static/js/app.cb9eb7853df1efe63c95.js","3086f0a98a0f73812b33065500b8f028"],["./static/js/manifest.3c89dab460961facc5de.js","d2407d24ddbac5d6dd0cf2cd7000e8fc"],["./static/js/vendor.f6377a11a892075cc9be.js","acf303bf6b909d8797ec7f7da540b0a9"]];
var cacheName = 'sw-precache-v3-vue-hn-' + (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);
});
};

var stripIgnoredUrlParameters = function (originalUrl,
ignoreUrlParametersMatching) {
var url = new URL(originalUrl);
// Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290
url.hash = '';

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, /./);
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());

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() {

return self.clients.claim();

})
);
});


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);
})
);
}
}
});







2 changes: 2 additions & 0 deletions www/static/js/app.cb9eb7853df1efe63c95.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions www/static/js/app.cb9eb7853df1efe63c95.js.map

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions www/static/js/app.ee9c8e5353798c95b13f.js

This file was deleted.

1 change: 0 additions & 1 deletion www/static/js/app.ee9c8e5353798c95b13f.js.map

This file was deleted.

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

Loading

0 comments on commit 7be2ce0

Please sign in to comment.