Skip to content

Commit 71188bb

Browse files
ragingwindaddyosmani
authored andcommitted
Add SW registration template injection (#21)
1 parent ea6bbd2 commit 71188bb

File tree

5 files changed

+82
-59
lines changed

5 files changed

+82
-59
lines changed

template/build/service-worker-dev.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This service worker file is effectively a 'no-op' that will reset any
2+
// previous service worker registered for the same host:port combination.
3+
// In the production build, this file is replaced with an actual service worker
4+
// file that will precache your site's local assets.
5+
// See https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432
6+
7+
self.addEventListener('install', () => self.skipWaiting());
8+
9+
self.addEventListener('activate', () => {
10+
self.clients.matchAll({ type: 'window' }).then(windowClients => {
11+
for (let windowClient of windowClients) {
12+
// Force open pages to refresh, so that they have a chance to load the
13+
// fresh navigation response from the local dev server.
14+
windowClient.navigate(windowClient.url);
15+
}
16+
});
17+
});

template/build/service-worker-prod.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
(function() {
2+
'use strict';
3+
4+
// Check to make sure service workers are supported in the current browser,
5+
// and that the current page is accessed from a secure origin. Using a
6+
// service worker from an insecure origin will trigger JS console errors.
7+
const isLocalhost = Boolean(window.location.hostname === 'localhost' ||
8+
// [::1] is the IPv6 localhost address.
9+
window.location.hostname === '[::1]' ||
10+
// 127.0.0.1/8 is considered localhost for IPv4.
11+
window.location.hostname.match(
12+
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
13+
)
14+
);
15+
16+
window.addEventListener('load', function() {
17+
if ('serviceWorker' in navigator &&
18+
(window.location.protocol === 'https:' || isLocalhost)) {
19+
navigator.serviceWorker.register('service-worker.js')
20+
.then(function(registration) {
21+
// updatefound is fired if service-worker.js changes.
22+
registration.onupdatefound = function() {
23+
// updatefound is also fired the very first time the SW is installed,
24+
// and there's no need to prompt for a reload at that point.
25+
// So check here to see if the page is already controlled,
26+
// i.e. whether there's an existing service worker.
27+
if (navigator.serviceWorker.controller) {
28+
// The updatefound event implies that registration.installing is set
29+
const installingWorker = registration.installing;
30+
31+
installingWorker.onstatechange = function() {
32+
switch (installingWorker.state) {
33+
case 'installed':
34+
// At this point, the old content will have been purged and the
35+
// fresh content will have been added to the cache.
36+
// It's the perfect time to display a "New content is
37+
// available; please refresh." message in the page's interface.
38+
break;
39+
40+
case 'redundant':
41+
throw new Error('The installing ' +
42+
'service worker became redundant.');
43+
44+
default:
45+
// Ignore
46+
}
47+
};
48+
}
49+
};
50+
}).catch(function(e) {
51+
console.error('Error during service worker registration:', e);
52+
});
53+
}
54+
});
55+
})();

template/build/webpack.dev.conf.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
var fs = require('fs')
2+
var path = require('path')
13
var utils = require('./utils')
24
var webpack = require('webpack')
35
var config = require('../config')
@@ -28,7 +30,9 @@ module.exports = merge(baseWebpackConfig, {
2830
new HtmlWebpackPlugin({
2931
filename: 'index.html',
3032
template: 'index.html',
31-
inject: true
33+
inject: true,
34+
serviceWorkerLoader: `<script>${fs.readFileSync(path.join(__dirname,
35+
'./service-worker-dev.js'), 'utf-8')}</script>`
3236
}),
3337
new FriendlyErrorsPlugin()
3438
]

template/build/webpack.prod.conf.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
var fs = require('fs')
12
var path = require('path')
23
var utils = require('./utils')
34
var webpack = require('webpack')
@@ -66,7 +67,9 @@ var webpackConfig = merge(baseWebpackConfig, {
6667
// https://github.com/kangax/html-minifier#options-quick-reference
6768
},
6869
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
69-
chunksSortMode: 'dependency'
70+
chunksSortMode: 'dependency',
71+
serviceWorkerLoader: `<script>${fs.readFileSync(path.join(__dirname,
72+
'./service-worker-prod.js'), 'utf-8')}</script>`
7073
}),
7174
// split vendor js into its own file
7275
new webpack.optimize.CommonsChunkPlugin({

template/index.html

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -28,63 +28,7 @@
2828
<body>
2929
<div id="app">This is your fallback content in case JavaScript fails to load.</div>
3030
<!-- Todo: only include in production -->
31-
<script>
32-
(function() {
33-
'use strict';
34-
35-
// Check to make sure service workers are supported in the current browser,
36-
// and that the current page is accessed from a secure origin. Using a
37-
// service worker from an insecure origin will trigger JS console errors.
38-
const isLocalhost = Boolean(window.location.hostname === 'localhost' ||
39-
// [::1] is the IPv6 localhost address.
40-
window.location.hostname === '[::1]' ||
41-
// 127.0.0.1/8 is considered localhost for IPv4.
42-
window.location.hostname.match(
43-
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
44-
)
45-
);
46-
47-
window.addEventListener('load', function() {
48-
if ('serviceWorker' in navigator &&
49-
(window.location.protocol === 'https:' || isLocalhost)) {
50-
navigator.serviceWorker.register('service-worker.js')
51-
.then(function(registration) {
52-
// updatefound is fired if service-worker.js changes.
53-
registration.onupdatefound = function() {
54-
// updatefound is also fired the very first time the SW is installed,
55-
// and there's no need to prompt for a reload at that point.
56-
// So check here to see if the page is already controlled,
57-
// i.e. whether there's an existing service worker.
58-
if (navigator.serviceWorker.controller) {
59-
// The updatefound event implies that registration.installing is set
60-
const installingWorker = registration.installing;
61-
62-
installingWorker.onstatechange = function() {
63-
switch (installingWorker.state) {
64-
case 'installed':
65-
// At this point, the old content will have been purged and the
66-
// fresh content will have been added to the cache.
67-
// It's the perfect time to display a "New content is
68-
// available; please refresh." message in the page's interface.
69-
break;
70-
71-
case 'redundant':
72-
throw new Error('The installing ' +
73-
'service worker became redundant.');
74-
75-
default:
76-
// Ignore
77-
}
78-
};
79-
}
80-
};
81-
}).catch(function(e) {
82-
console.error('Error during service worker registration:', e);
83-
});
84-
}
85-
});
86-
})();
87-
</script>
31+
<%= htmlWebpackPlugin.options.serviceWorkerLoader %>
8832
<!-- built files will be auto injected -->
8933
</body>
9034
</html>

0 commit comments

Comments
 (0)