Skip to content

Commit c15965c

Browse files
committed
Added SW
1 parent bac77ec commit c15965c

File tree

3 files changed

+166
-5
lines changed

3 files changed

+166
-5
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
React Service Worker
2-
=========
1+
# React Service Worker
32

43
Simple and powerful alternative for the default create-react-app registerServiceWorker
54

index.js

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,172 @@
11
'use strict';
22

3+
// In production, we register a service worker to serve assets from local cache.
4+
5+
// This lets the app load faster on subsequent visits in production, and gives
6+
// it offline capabilities. However, it also means that developers (and users)
7+
// will only see deployed updates on the "N+1" visit to a page, since previously
8+
// cached resources are updated in the background.
9+
10+
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
11+
312
/**
413
* The default register service worker function
14+
* @returns {AppServiceWorker}
515
*/
616
function registerServiceWorker() {
7-
// TODO
17+
return AppServiceWorker.getInstance()
18+
}
19+
20+
/**
21+
* App Service Worker Class
22+
*
23+
* @export
24+
* @class AppServiceWorker
25+
*/
26+
export class AppServiceWorker {
27+
/**
28+
* Creates an instance of AppServiceWorker.
29+
*
30+
* @memberof AppServiceWorker
31+
*/
32+
constructor() {
33+
34+
this.isLocalhost = Boolean(
35+
window.location.hostname === "localhost" ||
36+
// [::1] is the IPv6 localhost address.
37+
window.location.hostname === "[::1]" ||
38+
// 127.0.0.1/8 is considered localhost for IPv4.
39+
window.location.hostname.match(
40+
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
41+
)
42+
);
43+
44+
this.installPromise = new Promise(resolve => this.installPromiseResolver = resolve)
45+
this.updatePromise = new Promise(resolve => this.updatePromiseResolver = resolve)
46+
47+
this.onUpdateFound(() => console.log("New content is available; please refresh."))
48+
this.onInstalled(() => console.log("Content is cached for offline use."))
49+
50+
}
51+
/**
52+
* Register the service worker
53+
*
54+
* @returns
55+
* @memberof AppServiceWorker
56+
*/
57+
register() {
58+
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
59+
// The URL constructor is available in all browsers that support SW.
60+
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
61+
if (publicUrl.origin !== window.location.origin) {
62+
// Our service worker won't work if PUBLIC_URL is on a different origin
63+
// from what our page is served on. This might happen if a CDN is used to
64+
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
65+
return;
66+
}
67+
68+
window.addEventListener("load", () => {
69+
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
70+
71+
if (this.isLocalhost) {
72+
// This is running on localhost. Lets check if a service worker still exists or not.
73+
this.checkValidServiceWorker(swUrl);
74+
75+
// Add some additional logging to localhost, pointing developers to the
76+
// service worker/PWA documentation.
77+
navigator.serviceWorker.ready.then(() => {
78+
console.log(
79+
"This web app is being served cache-first by a service " +
80+
"worker. To learn more, visit https://goo.gl/SC7cgQ"
81+
);
82+
});
83+
} else {
84+
// Is not local host. Just register service worker
85+
this.registerValidSW(swUrl);
86+
}
87+
});
88+
}
89+
return this
90+
}
91+
92+
registerValidSW(swUrl) {
93+
94+
navigator.serviceWorker
95+
.register(swUrl)
96+
.then(registration => {
97+
98+
registration.onupdatefound = () => {
99+
const installingWorker = registration.installing;
100+
installingWorker.onstatechange = () => {
101+
if (installingWorker.state === "installed") {
102+
if (navigator.serviceWorker.controller) {
103+
// At this point, the old content will have been purged and
104+
// the fresh content will have been added to the cache.
105+
// It's the perfect time to display a "New content is
106+
// available; please refresh." message in your web app.
107+
this.updatePromiseResolver()
108+
} else {
109+
// At this point, everything has been precached.
110+
// It's the perfect time to display a
111+
// "Content is cached for offline use." message.
112+
this.installPromiseResolver()
113+
}
114+
}
115+
};
116+
};
117+
})
118+
.catch(error => {
119+
console.error("Error during service worker registration:", error);
120+
});
121+
}
122+
123+
checkValidServiceWorker(swUrl) {
124+
// Check if the service worker can be found. If it can't reload the page.
125+
fetch(swUrl)
126+
.then(response => {
127+
// Ensure service worker exists, and that we really are getting a JS file.
128+
if (
129+
response.status === 404 ||
130+
response.headers.get("content-type").indexOf("javascript") === -1
131+
) {
132+
// No service worker found. Probably a different app. Reload the page.
133+
navigator.serviceWorker.ready.then(registration => {
134+
registration.unregister().then(() => {
135+
window.location.reload();
136+
});
137+
});
138+
} else {
139+
// Service worker found. Proceed as normal.
140+
this.registerValidSW(swUrl);
141+
}
142+
})
143+
.catch(() => {
144+
console.log(
145+
"No internet connection found. App is running in offline mode."
146+
);
147+
});
148+
}
149+
150+
unregister() {
151+
if ("serviceWorker" in navigator) {
152+
navigator.serviceWorker.ready.then(registration => {
153+
registration.unregister();
154+
});
155+
}
156+
}
157+
158+
onInstalled(callback) {
159+
this.installPromise.then(callback).catch(console.error)
160+
161+
}
162+
163+
onUpdateFound(callback) {
164+
this.updatePromise.then(callback).catch(console.error)
165+
}
166+
167+
static getInstance() {
168+
return this.instance ? this.instance : this.instance = new this().register()
169+
}
8170
}
9171

10-
export default registerServiceWorker;
172+
export default registerServiceWorker;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-service-worker",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"description": "Simple and powerful alternative for the default create-react-app registerServiceWorker",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)