|
1 | 1 | /// <reference types="node" />
|
2 |
| -// This optional code is used to register a service worker. |
3 |
| -// register() is not called by default. |
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 subsequent visits to a page, after all the |
8 |
| -// existing tabs open on the page have been closed, since previously cached |
9 |
| -// resources are updated in the background. |
10 |
| - |
11 |
| -// To learn more about the benefits of this model and instructions on how to |
12 |
| -// opt-in, read https://cra.link/PWA |
13 |
| -import { trimSuffix } from './utils/path' |
14 |
| - |
15 |
| -const BASE_URL = trimSuffix(import.meta.env.BASE_URL, '/') |
16 |
| - |
17 |
| -const isLocalhost = Boolean( |
18 |
| - window.location.hostname === 'localhost' || |
19 |
| - // [::1] is the IPv6 localhost address. |
20 |
| - window.location.hostname === '[::1]' || |
21 |
| - // 127.0.0.0/8 are considered localhost for IPv4. |
22 |
| - window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), |
23 |
| -) |
24 |
| - |
25 |
| -interface Config { |
26 |
| - onSuccess?: (registration: ServiceWorkerRegistration) => void |
27 |
| - onUpdate?: (registration: ServiceWorkerRegistration) => void |
28 |
| -} |
29 |
| - |
30 |
| -export function register(config?: Config) { |
31 |
| - if (import.meta.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { |
32 |
| - // The URL constructor is available in all browsers that support SW. |
33 |
| - const publicUrl = new URL(BASE_URL, window.location.href) |
34 |
| - if (publicUrl.origin !== window.location.origin) { |
35 |
| - // Our service worker won't work if BASE_URL is on a different origin |
36 |
| - // from what our page is served on. This might happen if a CDN is used to |
37 |
| - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 |
38 |
| - return |
39 |
| - } |
40 |
| - |
41 |
| - window.addEventListener('load', () => { |
42 |
| - const swUrl = `${BASE_URL}/service-worker.js` |
43 |
| - |
44 |
| - if (isLocalhost) { |
45 |
| - // This is running on localhost. Let's check if a service worker still exists or not. |
46 |
| - checkValidServiceWorker(swUrl, config) |
47 |
| - |
48 |
| - // Add some additional logging to localhost, pointing developers to the |
49 |
| - // service worker/PWA documentation. |
50 |
| - // eslint-disable-next-line @typescript-eslint/no-floating-promises |
51 |
| - navigator.serviceWorker.ready.then((reg) => { |
52 |
| - console.log( |
53 |
| - 'This web app is being served cache-first by a service ' + |
54 |
| - 'worker. To learn more, visit https://cra.link/PWA', |
55 |
| - ) |
56 |
| - reg.update().catch((err) => { |
57 |
| - console.error('Failed to update service worker: ', err) |
58 |
| - }) |
59 |
| - }) |
60 |
| - } else { |
61 |
| - // Is not localhost. Just register service worker |
62 |
| - registerValidSW(swUrl, config) |
63 |
| - } |
64 |
| - }) |
65 |
| - } |
66 |
| -} |
67 |
| - |
68 |
| -/** |
69 |
| - * Manually registers service worker |
70 |
| - * |
71 |
| - * @param config |
72 |
| - */ |
73 |
| -export function manualRegister(config?: Config) { |
74 |
| - if (import.meta.env.DEV) { |
75 |
| - return |
76 |
| - } |
77 |
| - if (!('serviceWorker' in navigator)) { |
78 |
| - return |
79 |
| - } |
80 |
| - |
81 |
| - const publicUrl = new URL(BASE_URL, window.location.href) |
82 |
| - if (publicUrl.origin !== window.location.origin) { |
83 |
| - return |
84 |
| - } |
85 |
| - |
86 |
| - const swUrl = `${BASE_URL}/service-worker.js` |
87 |
| - if (isLocalhost) { |
88 |
| - checkValidServiceWorker(swUrl, config) |
89 |
| - return |
90 |
| - } |
91 |
| - |
92 |
| - registerValidSW(swUrl, config) |
93 |
| -} |
94 |
| - |
95 |
| -function registerValidSW(swUrl: string, config?: Config) { |
96 |
| - navigator.serviceWorker |
97 |
| - .register(swUrl) |
98 |
| - .then((registration) => { |
99 |
| - registration.onupdatefound = () => { |
100 |
| - const installingWorker = registration.installing |
101 |
| - if (installingWorker == null) { |
102 |
| - return |
103 |
| - } |
104 |
| - installingWorker.onstatechange = () => { |
105 |
| - if (installingWorker.state === 'installed') { |
106 |
| - if (navigator.serviceWorker.controller) { |
107 |
| - // At this point, the updated precached content has been fetched, |
108 |
| - // but the previous service worker will still serve the older |
109 |
| - // content until all client tabs are closed. |
110 |
| - console.log( |
111 |
| - 'New content is available and will be used when all ' + |
112 |
| - 'tabs for this page are closed. See https://cra.link/PWA.', |
113 |
| - ) |
114 |
| - |
115 |
| - // Execute callback |
116 |
| - if (config?.onUpdate) { |
117 |
| - config.onUpdate(registration) |
118 |
| - } |
119 |
| - } else { |
120 |
| - // At this point, everything has been precached. |
121 |
| - // It's the perfect time to display a |
122 |
| - // "Content is cached for offline use." message. |
123 |
| - console.log('Content is cached for offline use.') |
124 |
| - |
125 |
| - // Execute callback |
126 |
| - if (config?.onSuccess) { |
127 |
| - config.onSuccess(registration) |
128 |
| - } |
129 |
| - } |
130 |
| - } |
131 |
| - } |
132 |
| - } |
133 |
| - }) |
134 |
| - .catch((error) => { |
135 |
| - console.error('Error during service worker registration:', error) |
136 |
| - }) |
137 |
| -} |
138 |
| - |
139 |
| -function checkValidServiceWorker(swUrl: string, config?: Config) { |
140 |
| - // Check if the service worker can be found. If it can't reload the page. |
141 |
| - fetch(swUrl, { |
142 |
| - headers: { 'Service-Worker': 'script' }, |
143 |
| - }) |
144 |
| - .then((response) => { |
145 |
| - // Ensure service worker exists, and that we really are getting a JS file. |
146 |
| - const contentType = response.headers.get('content-type') |
147 |
| - if (response.status === 404 || (contentType != null && !contentType.includes('javascript'))) { |
148 |
| - // No service worker found. Probably a different app. Reload the page. |
149 |
| - // eslint-disable-next-line @typescript-eslint/no-floating-promises |
150 |
| - navigator.serviceWorker.ready.then((registration) => { |
151 |
| - // eslint-disable-next-line @typescript-eslint/no-floating-promises |
152 |
| - registration.unregister().then(() => { |
153 |
| - window.location.reload() |
154 |
| - }) |
155 |
| - }) |
156 |
| - } else { |
157 |
| - // Service worker found. Proceed as normal. |
158 |
| - registerValidSW(swUrl, config) |
159 |
| - } |
160 |
| - }) |
161 |
| - .catch(() => { |
162 |
| - console.log('No internet connection found. App is running in offline mode.') |
163 |
| - }) |
164 |
| -} |
165 | 2 |
|
166 | 3 | export function unregister() {
|
167 | 4 | if ('serviceWorker' in navigator) {
|
|
0 commit comments