Skip to content

Commit d269f55

Browse files
committed
Part 3: Fixing Service Worker
1 parent 565abd8 commit d269f55

File tree

5 files changed

+232
-4
lines changed

5 files changed

+232
-4
lines changed

client/package-lock.json

Lines changed: 129 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010
"react-redux": "^5.0.6",
1111
"react-scripts": "1.0.17",
1212
"redux": "^3.7.2",
13-
"redux-thunk": "^2.2.0"
13+
"redux-thunk": "^2.2.0",
14+
"workbox-cli": "^2.1.2",
15+
"workbox-sw": "^2.1.2"
1416
},
1517
"scripts": {
1618
"start": "react-scripts start",
17-
"build": "react-scripts build && npm run move-build-to-server",
19+
"build": "react-scripts build && npm run generate-sw && npm run move-build-to-server",
20+
"generate-sw": "workbox inject:manifest && cp node_modules/workbox-sw/build/importScripts/workbox-sw.prod* build",
1821
"move-build-to-server": "mv build _build && mv _build ../server && cd ../server && rm -rf public && mv _build public && mv public/index.html public/layout.html",
1922
"test": "react-scripts test --env=jsdom",
2023
"eject": "react-scripts eject"

client/src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'isomorphic-fetch'
33
import ReactDOM from 'react-dom'
44
import './index.css'
55
import App from './App'
6-
import { unregister } from './registerServiceWorker'
6+
import registerServiceWorker from './registerServiceWorker'
77
import thunkMiddleware from 'redux-thunk'
88
import { Provider } from 'react-redux'
99
import { createStore, applyMiddleware } from 'redux'
@@ -20,4 +20,4 @@ ReactDOM.render(
2020
document.getElementById('root')
2121
)
2222

23-
unregister()
23+
registerServiceWorker()

client/src/service-worker.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
importScripts('workbox-sw.prod.v2.1.2.js')
2+
3+
const workbox = new WorkboxSW({
4+
skipWaiting: true,
5+
clientsClaim: true
6+
})
7+
8+
// following array will be filled with filenames
9+
// from `build/` folder when `generate-sw` script runs
10+
workbox.precache([])
11+
12+
// cache index.html when service worker gets installed
13+
self.addEventListener('install', updateIndexCache)
14+
15+
// the listener catches all http requests coming from
16+
// the browser at my website
17+
self.addEventListener('fetch', event => {
18+
const url = new URL(event.request.url)
19+
// I want to let event through without modifying if
20+
// any of the following conditions are met
21+
if (
22+
// if it's a request for a precached file
23+
isPrecached(url) ||
24+
// if it's a request for a static file (not index.html)
25+
isStaticFile(url) ||
26+
// if it's an external request to another domain
27+
isExternal(url) ||
28+
// if it's a GET request to /api/* url
29+
isGetApi(event, url)
30+
) { return }
31+
32+
// when an API action happens, for example,
33+
// "DELETE /api/session" that logs user out,
34+
// I let the request through and update index.html
35+
// cache after it's done
36+
if (event.request.method !== 'GET') {
37+
return event.respondWith(
38+
fetch(event.request)
39+
.then(response => {
40+
updateIndexCache()
41+
return response
42+
})
43+
)
44+
}
45+
46+
// I serve index.html network-first on any request that
47+
// reached this line
48+
event.respondWith(
49+
fetch(indexRequest())
50+
.then(response => {
51+
updateIndexCache()
52+
return response
53+
})
54+
.catch(() => caches.match(indexRequest()))
55+
)
56+
})
57+
58+
function isPrecached({ href }) {
59+
return workbox._revisionedCacheManager._parsedCacheUrls.includes(href)
60+
}
61+
62+
function isStaticFile({ pathname }) {
63+
return pathname.includes('.') && pathname !== '/index.html'
64+
}
65+
66+
function isExternal({ origin }) {
67+
return origin !== location.origin
68+
}
69+
70+
// if your api has a different prefix, e.g., /api/v1/,
71+
// just update RegExp accordingly
72+
function isGetApi({ request }, { pathname }) {
73+
return request.method === 'GET' && /^\/api\/.+/.test(pathname)
74+
}
75+
76+
async function updateIndexCache() {
77+
const cache = await caches.open('dynamic-v1')
78+
cache.add(indexRequest())
79+
}
80+
81+
function indexRequest() {
82+
return new Request('index.html', { credentials: 'same-origin' })
83+
}

client/workbox-cli-config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
"globDirectory": "build/",
3+
"globPatterns": [
4+
"**/*.{json,ico,html,js,css,woff2,woff}"
5+
],
6+
"swSrc": "./src/service-worker.js",
7+
"swDest": "build/service-worker.js",
8+
"globIgnores": [
9+
"../workbox-cli-config.js",
10+
"asset-manifest.json",
11+
"index.html"
12+
]
13+
};

0 commit comments

Comments
 (0)