Skip to content
This repository was archived by the owner on Apr 22, 2022. It is now read-only.

Commit 24e8deb

Browse files
Merge b327553 into 5bcc14e
2 parents 5bcc14e + b327553 commit 24e8deb

File tree

7 files changed

+251
-20
lines changed

7 files changed

+251
-20
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,3 @@ cypress/screenshots
2929

3030
# IntellJ
3131
.idea
32-
33-
# Electron
34-
/out

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"react-dom": "^16.13.1",
3636
"react-redux": "^7.2.1",
3737
"react-router-dom": "^5.2.0",
38-
"react-scripts": "4.0.0",
38+
"react-scripts": "4.0.1",
3939
"react-test-renderer": "^16.13.1",
4040
"redux": "^4.0.5",
4141
"redux-logger": "^3.0.6",

src/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import ReactDOM from "react-dom";
33
import "./index.css";
44
import App from "./App";
5+
import * as serviceWorkerRegistration from "./serviceWorkerRegistration";
56
import reportWebVitals from "./reportWebVitals";
67

78
import { Provider } from "react-redux";
@@ -49,6 +50,11 @@ ReactDOM.render(
4950
document.getElementById("root")
5051
);
5152

53+
// If you want your app to work offline and load faster, you can change
54+
// unregister() to register() below. Note this comes with some pitfalls.
55+
// Learn more about service workers: https://cra.link/PWA
56+
serviceWorkerRegistration.register();
57+
5258
// If you want to start measuring performance in your app, pass a function
5359
// to log results (for example: reportWebVitals(console.log))
5460
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

src/reportWebVitals.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { ReportHandler } from 'web-vitals';
1+
import { ReportHandler } from "web-vitals";
22

33
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
44
if (onPerfEntry && onPerfEntry instanceof Function) {
5-
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6-
getCLS(onPerfEntry);
5+
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6+
getCLS(onPerfEntry);
77
getFID(onPerfEntry);
88
getFCP(onPerfEntry);
99
getLCP(onPerfEntry);
1010
getTTFB(onPerfEntry);
1111
});
1212
}
13-
}
13+
};
1414

1515
export default reportWebVitals;

src/service-worker.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/// <reference lib="webworker" />
2+
/* eslint-disable no-restricted-globals */
3+
4+
// This service worker can be customized!
5+
// See https://developers.google.com/web/tools/workbox/modules
6+
// for the list of available Workbox modules, or add any other
7+
// code you'd like.
8+
// You can also remove this file if you'd prefer not to use a
9+
// service worker, and the Workbox build step will be skipped.
10+
11+
import { clientsClaim } from "workbox-core";
12+
import { ExpirationPlugin } from "workbox-expiration";
13+
import { precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching";
14+
import { registerRoute } from "workbox-routing";
15+
import { StaleWhileRevalidate } from "workbox-strategies";
16+
17+
declare const self: ServiceWorkerGlobalScope;
18+
19+
clientsClaim();
20+
21+
// Precache all of the assets generated by your build process.
22+
// Their URLs are injected into the manifest variable below.
23+
// This variable must be present somewhere in your service worker file,
24+
// even if you decide not to use precaching. See https://cra.link/PWA
25+
precacheAndRoute(self.__WB_MANIFEST);
26+
27+
// Set up App Shell-style routing, so that all navigation requests
28+
// are fulfilled with your index.html shell. Learn more at
29+
// https://developers.google.com/web/fundamentals/architecture/app-shell
30+
const fileExtensionRegexp = new RegExp("/[^/?]+\\.[^/]+$");
31+
registerRoute(
32+
// Return false to exempt requests from being fulfilled by index.html.
33+
({ request, url }: { request: Request; url: URL }) => {
34+
// If this isn't a navigation, skip.
35+
if (request.mode !== "navigate") {
36+
return false;
37+
}
38+
39+
// If this is a URL that starts with /_, skip.
40+
if (url.pathname.startsWith("/_")) {
41+
return false;
42+
}
43+
44+
// If this looks like a URL for a resource, because it contains
45+
// a file extension, skip.
46+
if (url.pathname.match(fileExtensionRegexp)) {
47+
return false;
48+
}
49+
50+
// Return true to signal that we want to use the handler.
51+
return true;
52+
},
53+
createHandlerBoundToURL(process.env.PUBLIC_URL + "/index.html")
54+
);
55+
56+
// An example runtime caching route for requests that aren't handled by the
57+
// precache, in this case same-origin .png requests like those from in public/
58+
registerRoute(
59+
// Add in any other file extensions or routing criteria as needed.
60+
({ url }) =>
61+
url.origin === self.location.origin && url.pathname.endsWith(".png"),
62+
// Customize this strategy as needed, e.g., by changing to CacheFirst.
63+
new StaleWhileRevalidate({
64+
cacheName: "images",
65+
plugins: [
66+
// Ensure that once this runtime cache reaches a maximum size the
67+
// least-recently used images are removed.
68+
new ExpirationPlugin({ maxEntries: 50 }),
69+
],
70+
})
71+
);
72+
73+
// This allows the web app to trigger skipWaiting via
74+
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
75+
self.addEventListener("message", (event) => {
76+
if (event.data && event.data.type === "SKIP_WAITING") {
77+
self.skipWaiting();
78+
}
79+
});
80+
81+
// Any other custom service worker logic can go here.

src/serviceWorkerRegistration.ts

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

yarn.lock

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9318,7 +9318,7 @@ [email protected]:
93189318
strip-ansi "^5.1.0"
93199319
through "^2.3.6"
93209320

9321-
inquirer@7.3.3, inquirer@^7.0.0:
9321+
inquirer@^7.0.0:
93229322
version "7.3.3"
93239323
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003"
93249324
integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==
@@ -13674,7 +13674,7 @@ promise@^8.1.0:
1367413674
dependencies:
1367513675
asap "~2.0.6"
1367613676

13677-
prompts@^2.0.1:
13677+
prompts@2.4.0, prompts@^2.0.1:
1367813678
version "2.4.0"
1367913679
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7"
1368013680
integrity sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==
@@ -13966,10 +13966,10 @@ react-dev-utils@^10.0.0:
1396613966
strip-ansi "6.0.0"
1396713967
text-table "0.2.0"
1396813968

13969-
react-dev-utils@^11.0.0:
13970-
version "11.0.0"
13971-
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.0.tgz#9fdb1b173f4ffc1f23fcf98465d93b16a860b73e"
13972-
integrity sha512-uIZTUZXB5tbiM/0auUkLVjWhZGM7DSI304iGunyhA9m985iIDVXd9I4z6MkNa9jeLzeUJbU9A7TUNrcbXAahxw==
13969+
react-dev-utils@^11.0.1:
13970+
version "11.0.1"
13971+
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.1.tgz#30106c2055acfd6b047d2dc478a85c356e66fe45"
13972+
integrity sha512-rlgpCupaW6qQqvu0hvv2FDv40QG427fjghV56XyPcP5aKtOAPzNAhQ7bHqk1YdS2vpW1W7aSV3JobedxuPlBAA==
1397313973
dependencies:
1397413974
"@babel/code-frame" "7.10.4"
1397513975
address "1.1.2"
@@ -13985,11 +13985,11 @@ react-dev-utils@^11.0.0:
1398513985
globby "11.0.1"
1398613986
gzip-size "5.1.1"
1398713987
immer "7.0.9"
13988-
inquirer "7.3.3"
1398913988
is-root "2.1.0"
1399013989
loader-utils "2.0.0"
1399113990
open "^7.0.2"
1399213991
pkg-up "3.1.0"
13992+
prompts "2.4.0"
1399313993
react-error-overlay "^6.0.8"
1399413994
recursive-readdir "2.2.2"
1399513995
shell-quote "1.7.2"
@@ -14209,10 +14209,10 @@ [email protected]:
1420914209
tiny-invariant "^1.0.2"
1421014210
tiny-warning "^1.0.0"
1421114211

14212-
14213-
version "4.0.0"
14214-
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.0.tgz#36f3d84ffff708ac0618fd61e71eaaea11c26417"
14215-
integrity sha512-icJ/ctwV5XwITUOupBP9TUVGdWOqqZ0H08tbJ1kVC5VpNWYzEZ3e/x8axhV15ZXRsixLo27snwQE7B6Zd9J2Tg==
14212+
14213+
version "4.0.1"
14214+
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.1.tgz#34974c0f4cfdf1655906c95df6a04d80db8b88f0"
14215+
integrity sha512-NnniMSC/wjwhcJAyPJCWtxx6CWONqgvGgV9+QXj1bwoW/JI++YF1eEf3Upf/mQ9KmP57IBdjzWs1XvnPq7qMTQ==
1421614216
dependencies:
1421714217
"@babel/core" "7.12.3"
1421814218
"@pmmmwh/react-refresh-webpack-plugin" "0.4.2"
@@ -14256,8 +14256,9 @@ [email protected]:
1425614256
postcss-normalize "8.0.1"
1425714257
postcss-preset-env "6.7.0"
1425814258
postcss-safe-parser "5.0.2"
14259+
prompts "2.4.0"
1425914260
react-app-polyfill "^2.0.0"
14260-
react-dev-utils "^11.0.0"
14261+
react-dev-utils "^11.0.1"
1426114262
react-refresh "^0.8.3"
1426214263
resolve "1.18.1"
1426314264
resolve-url-loader "^3.1.2"

0 commit comments

Comments
 (0)