Skip to content

Commit

Permalink
Add SW registration template injection (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
ragingwind authored and addyosmani committed May 31, 2017
1 parent ea6bbd2 commit 71188bb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 59 deletions.
17 changes: 17 additions & 0 deletions template/build/service-worker-dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// In the production build, this file is replaced with an actual service worker
// file that will precache your site's local assets.
// See https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432

self.addEventListener('install', () => self.skipWaiting());

self.addEventListener('activate', () => {
self.clients.matchAll({ type: 'window' }).then(windowClients => {
for (let windowClient of windowClients) {
// Force open pages to refresh, so that they have a chance to load the
// fresh navigation response from the local dev server.
windowClient.navigate(windowClient.url);
}
});
});
55 changes: 55 additions & 0 deletions template/build/service-worker-prod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
(function() {
'use strict';

// Check to make sure service workers are supported in the current browser,
// and that the current page is accessed from a secure origin. Using a
// service worker from an insecure origin will trigger JS console errors.
const isLocalhost = Boolean(window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);

window.addEventListener('load', function() {
if ('serviceWorker' in navigator &&
(window.location.protocol === 'https:' || isLocalhost)) {
navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
// updatefound is fired if service-worker.js changes.
registration.onupdatefound = function() {
// updatefound is also fired the very first time the SW is installed,
// and there's no need to prompt for a reload at that point.
// So check here to see if the page is already controlled,
// i.e. whether there's an existing service worker.
if (navigator.serviceWorker.controller) {
// The updatefound event implies that registration.installing is set
const installingWorker = registration.installing;

installingWorker.onstatechange = function() {
switch (installingWorker.state) {
case 'installed':
// At this point, the old content will have been purged and the
// fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in the page's interface.
break;

case 'redundant':
throw new Error('The installing ' +
'service worker became redundant.');

default:
// Ignore
}
};
}
};
}).catch(function(e) {
console.error('Error during service worker registration:', e);
});
}
});
})();
6 changes: 5 additions & 1 deletion template/build/webpack.dev.conf.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
var fs = require('fs')
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
Expand Down Expand Up @@ -28,7 +30,9 @@ module.exports = merge(baseWebpackConfig, {
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
inject: true,
serviceWorkerLoader: `<script>${fs.readFileSync(path.join(__dirname,
'./service-worker-dev.js'), 'utf-8')}</script>`
}),
new FriendlyErrorsPlugin()
]
Expand Down
5 changes: 4 additions & 1 deletion template/build/webpack.prod.conf.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var fs = require('fs')
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
Expand Down Expand Up @@ -66,7 +67,9 @@ var webpackConfig = merge(baseWebpackConfig, {
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
chunksSortMode: 'dependency',
serviceWorkerLoader: `<script>${fs.readFileSync(path.join(__dirname,
'./service-worker-prod.js'), 'utf-8')}</script>`
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
Expand Down
58 changes: 1 addition & 57 deletions template/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,63 +28,7 @@
<body>
<div id="app">This is your fallback content in case JavaScript fails to load.</div>
<!-- Todo: only include in production -->
<script>
(function() {
'use strict';

// Check to make sure service workers are supported in the current browser,
// and that the current page is accessed from a secure origin. Using a
// service worker from an insecure origin will trigger JS console errors.
const isLocalhost = Boolean(window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);

window.addEventListener('load', function() {
if ('serviceWorker' in navigator &&
(window.location.protocol === 'https:' || isLocalhost)) {
navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
// updatefound is fired if service-worker.js changes.
registration.onupdatefound = function() {
// updatefound is also fired the very first time the SW is installed,
// and there's no need to prompt for a reload at that point.
// So check here to see if the page is already controlled,
// i.e. whether there's an existing service worker.
if (navigator.serviceWorker.controller) {
// The updatefound event implies that registration.installing is set
const installingWorker = registration.installing;

installingWorker.onstatechange = function() {
switch (installingWorker.state) {
case 'installed':
// At this point, the old content will have been purged and the
// fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in the page's interface.
break;

case 'redundant':
throw new Error('The installing ' +
'service worker became redundant.');

default:
// Ignore
}
};
}
};
}).catch(function(e) {
console.error('Error during service worker registration:', e);
});
}
});
})();
</script>
<%= htmlWebpackPlugin.options.serviceWorkerLoader %>
<!-- built files will be auto injected -->
</body>
</html>

0 comments on commit 71188bb

Please sign in to comment.