Skip to content

Commit 42a6c15

Browse files
committed
add serviceWorker
1 parent 9911c9b commit 42a6c15

File tree

8 files changed

+609
-14
lines changed

8 files changed

+609
-14
lines changed

build/webpack.base.conf.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ const path = require('path'),
22
webpack = require('webpack'),
33
styleRules = require('./styleLoaderConf'),
44
CopyWebpackPlugin = require('copy-webpack-plugin'),
5-
MiniCssExtractPlugin = require("mini-css-extract-plugin");
5+
MiniCssExtractPlugin = require("mini-css-extract-plugin"),
6+
ManifestPlugin = require('webpack-manifest-plugin'),
7+
SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
68

79
const _PROD_ = process.env.NODE_ENV === 'production';
810

@@ -169,6 +171,26 @@ module.exports = {
169171
// },
170172
// _DEV_: JSON.stringify(_DEV_),
171173
// }),
174+
new ManifestPlugin({
175+
fileName: 'asset-manifest.json'
176+
}),
177+
new SWPrecacheWebpackPlugin({
178+
dontCacheBustUrlsMatching: /\.\w{8}\./,
179+
filename: 'serviceWorker.js',
180+
logger(message) {
181+
console.log(message);
182+
if (message.indexOf('Total precache size is') === 0) {
183+
return;
184+
}
185+
if (message.indexOf('Skipping static resource') === 0) {
186+
return;
187+
}
188+
},
189+
minify: true,
190+
navigateFallback: '/index.html',
191+
navigateFallbackWhitelist: [/^(?!\/__).*/],
192+
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
193+
}),
172194
new MiniCssExtractPlugin({
173195
filename: "static/css/[name].[contenthash].css",
174196
}),

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@
4747
"react-hot-loader": "^4.3.12",
4848
"sass-loader": "^7.1.0",
4949
"style-loader": "^0.23.1",
50+
"sw-precache-webpack-plugin": "^0.11.5",
5051
"typescript": "^3.1.6",
5152
"uglifyjs-webpack-plugin": "^2.0.1",
5253
"url-loader": "^1.1.2",
5354
"webpack": "^4.26.1",
5455
"webpack-cli": "^3.1.2",
5556
"webpack-dev-server": "^3.1.10",
57+
"webpack-manifest-plugin": "^2.0.4",
5658
"webpack-merge": "^4.1.4"
5759
}
5860
}

src/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<meta http-equiv="X-UA-Compatible" content="ie=edge">
77
<title><%= htmlWebpackPlugin.options.title %></title>
88
<link rel="icon" href="/favicon.ico" type="image/x-icon"/>
9+
<link rel="manifest" href="/manifest.json">
910
<script>
1011
var _html = document.documentElement;
1112
function getSize() {
@@ -20,7 +21,7 @@
2021
}
2122
getSize();
2223

23-
var timer;
24+
var timer = null;
2425
window.addEventListener('resize', function(e) {
2526
clearTimeout(timer);
2627
timer = setTimeout(function(){getSize()}, 300);

src/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import App from './pages/app';
44
import './assets/scss/app.scss';
55
import 'antd/dist/antd.css'
66
import 'quill/dist/quill.snow.css';
7+
import serviceWorker from './serviceWorker'
78

89
ReactDOM.render(
910
<App/>,
1011
document.getElementById('app')
11-
);
12+
);
13+
serviceWorker()

src/serviceWorker.ts

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

statics/logo.svg

Lines changed: 9 additions & 0 deletions
Loading

statics/manifest.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "React",
3+
"icons": [
4+
{
5+
"src": "logo.svg",
6+
"sizes": "192x192",
7+
"type": "image/svg"
8+
}
9+
],
10+
"theme_color": "#ffffff",
11+
"background_color": "#ffffff",
12+
"start_url": "/React-PWA/",
13+
"display": "standalone"
14+
}

0 commit comments

Comments
 (0)