UNPKG

4.17 kBPlain TextView Raw
1// tslint:disable:no-console
2// In production, we register a service worker to serve assets from local cache.
3
4// This lets the app load faster on subsequent visits in production, and gives
5// it offline capabilities. However, it also means that developers (and users)
6// will only see deployed updates on the 'N+1' visit to a page, since previously
7// cached resources are updated in the background.
8
9// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
10// This link also includes instructions on opting out of this behavior.
11
12const isLocalhost = Boolean(
13 window.location.hostname === 'localhost' ||
14 // [::1] is the IPv6 localhost address.
15 window.location.hostname === '[::1]' ||
16 // 127.0.0.1/8 is considered localhost for IPv4.
17 window.location.hostname.match(
18 /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
19 )
20);
21
22export default function register() {
23 if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
24 // The URL constructor is available in all browsers that support SW.
25 const publicUrl = new URL(
26 process.env.PUBLIC_URL!,
27 window.location.toString()
28 );
29 if (publicUrl.origin !== window.location.origin) {
30 // Our service worker won't work if PUBLIC_URL is on a different origin
31 // from what our page is served on. This might happen if a CDN is used to
32 // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
33 return;
34 }
35
36 window.addEventListener('load', () => {
37 const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
38
39 if (!isLocalhost) {
40 // Is not local host. Just register service worker
41 registerValidSW(swUrl);
42 } else {
43 // This is running on localhost. Lets check if a service worker still exists or not.
44 checkValidServiceWorker(swUrl);
45 }
46 });
47 }
48}
49
50function registerValidSW(swUrl: string) {
51 navigator.serviceWorker
52 .register(swUrl)
53 .then(registration => {
54 registration.onupdatefound = () => {
55 const installingWorker = registration.installing;
56 if (installingWorker) {
57 installingWorker.onstatechange = () => {
58 if (installingWorker.state === 'installed') {
59 if (navigator.serviceWorker.controller) {
60 // At this point, the old content will have been purged and
61 // the fresh content will have been added to the cache.
62 // It's the perfect time to display a 'New content is
63 // available; please refresh.' message in your web app.
64 console.log('New content is available; please refresh.');
65 } else {
66 // At this point, everything has been precached.
67 // It's the perfect time to display a
68 // 'Content is cached for offline use.' message.
69 console.log('Content is cached for offline use.');
70 }
71 }
72 };
73 }
74 };
75 })
76 .catch(error => {
77 console.error('Error during service worker registration:', error);
78 });
79}
80
81function checkValidServiceWorker(swUrl: string) {
82 // Check if the service worker can be found. If it can't reload the page.
83 fetch(swUrl)
84 .then(response => {
85 // Ensure service worker exists, and that we really are getting a JS file.
86 if (
87 response.status === 404 ||
88 response.headers.get('content-type')!.indexOf('javascript') === -1
89 ) {
90 // No service worker found. Probably a different app. Reload the page.
91 navigator.serviceWorker.ready.then(registration => {
92 registration.unregister().then(() => {
93 window.location.reload();
94 });
95 });
96 } else {
97 // Service worker found. Proceed as normal.
98 registerValidSW(swUrl);
99 }
100 })
101 .catch(() => {
102 console.log(
103 'No internet connection found. App is running in offline mode.'
104 );
105 });
106}
107
108export function unregister() {
109 if ('serviceWorker' in navigator) {
110 navigator.serviceWorker.ready.then(registration => {
111 registration.unregister();
112 });
113 }
114}