Skip to content

Commit

Permalink
Part 3: Fixing Service Worker
Browse files Browse the repository at this point in the history
  • Loading branch information
vfeskov committed Dec 28, 2017
1 parent 565abd8 commit d2f1473
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 4 deletions.
129 changes: 129 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions client/package.json
Expand Up @@ -10,11 +10,14 @@
"react-redux": "^5.0.6",
"react-scripts": "1.0.17",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0"
"redux-thunk": "^2.2.0",
"workbox-cli": "^2.1.2",
"workbox-sw": "^2.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build && npm run move-build-to-server",
"build": "react-scripts build && npm run generate-sw && npm run move-build-to-server",
"generate-sw": "workbox inject:manifest && cp node_modules/workbox-sw/build/importScripts/workbox-sw.prod* build",
"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",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
Expand Down
4 changes: 2 additions & 2 deletions client/src/index.js
Expand Up @@ -3,7 +3,7 @@ import 'isomorphic-fetch'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { unregister } from './registerServiceWorker'
import registerServiceWorker from './registerServiceWorker'
import thunkMiddleware from 'redux-thunk'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
Expand All @@ -20,4 +20,4 @@ ReactDOM.render(
document.getElementById('root')
)

unregister()
registerServiceWorker()
80 changes: 80 additions & 0 deletions client/src/service-worker.js
@@ -0,0 +1,80 @@
importScripts('workbox-sw.prod.v2.1.2.js')

const workbox = new WorkboxSW({
skipWaiting: true,
clientsClaim: true
})

// following array will be filled with filenames
// from `build/` folder when `generate-sw` script runs
workbox.precache([])

// the listener catches all http requests coming from
// the browser at my website
self.addEventListener('fetch', event => {
const url = new URL(event.request.url)
// I want to let event through without modifying if
// any of the following conditions are met
if (
// if it's a request for a precached file
isPrecached(url) ||
// if it's a request for a static file (not index.html)
isStaticFile(url) ||
// if it's an external request to another domain
isExternal(url) ||
// if it's a GET request to /api/* url
isGetApi(event, url)
) { return }

// when an API action happens, for example,
// "DELETE /api/session" that logs user out,
// I let the request through and update index.html
// cache after it's done
if (event.request.method !== 'GET') {
return event.respondWith(
fetch(event.request)
.then(response => {
updateIndexCache()
return response
})
)
}

// I serve index.html network-first on any request that
// reached this line
event.respondWith(
fetch(indexRequest())
.then(response => {
updateIndexCache()
return response
})
.catch(() => caches.match(indexRequest()))
)
})

function isPrecached({ href }) {
return workbox._revisionedCacheManager._parsedCacheUrls.includes(href)
}

function isStaticFile({ pathname }) {
return pathname.includes('.') && pathname !== '/index.html'
}

function isExternal({ origin }) {
return origin !== location.origin
}

// if your api has a different prefix, e.g., /api/v1/,
// just update RegExp accordingly
function isGetApi({ request }, { pathname }) {
return request.method === 'GET' && /^\/api\/.+/.test(pathname)
}

async function updateIndexCache() {
const cache = await caches.open('dynamic-v1')
cache.add(indexRequest())
}

function indexRequest() {
return new Request('index.html', { credentials: 'same-origin' })
}
13 changes: 13 additions & 0 deletions client/workbox-cli-config.js
@@ -0,0 +1,13 @@
module.exports = {
"globDirectory": "build/",
"globPatterns": [
"**/*.{json,ico,html,js,css,woff2,woff}"
],
"swSrc": "./src/service-worker.js",
"swDest": "build/service-worker.js",
"globIgnores": [
"../workbox-cli-config.js",
"asset-manifest.json",
"index.html"
]
};

0 comments on commit d2f1473

Please sign in to comment.