Skip to content

Commit e5ac3b6

Browse files
committed
feat: disable service worker by default
1 parent 33f11ba commit e5ac3b6

File tree

4 files changed

+58
-28
lines changed

4 files changed

+58
-28
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ my-app/
6262
│ ├── Main.elm
6363
│ ├── index.js
6464
│ ├── main.css
65-
│ └── registerServiceWorker.js
65+
│ └── serviceWorker.js
6666
└── tests
6767
└── Tests.elm
6868
```

template/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ my-app/
9999
│ ├── Main.elm
100100
│ ├── index.js
101101
│ ├── main.css
102-
│ └── registerServiceWorker.js
102+
│ └── serviceWorker.js
103103
└── tests
104104
└── Tests.elm
105105
```
@@ -734,15 +734,15 @@ it may take up to 24 hours for the cache to be invalidated.
734734

735735
1. Service workers [require HTTPS](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers#you_need_https), although to facilitate local testing, that policy[does not apply to `localhost`](http://stackoverflow.com/questions/34160509/options-for-testing-service-workers-via-http/34161385#34161385). If your production web server does not support HTTPS, then the service worker registration will fail, but the rest of your web app will remain functional.
736736

737-
1. Service workers are [not currently supported](https://jakearchibald.github.io/isserviceworkerready/) in all web browsers. Service worker registration [won't be attempted](src/registerServiceWorker.js) on browsers that lack support.
737+
1. Service workers are [not currently supported](https://jakearchibald.github.io/isserviceworkerready/) in all web browsers. Service worker registration [won't be attempted](src/serviceWorker.js) on browsers that lack support.
738738

739739
1. The service worker is only enabled in the [production environment](#deployment), e.g. the output of `npm run build`. It's recommended that you do not enable an offline-first service worker in a development environment, as it can lead to frustration when previously cached assets are used and do not include the latest changes you've made locally.
740740

741741
1. If you _need_ to test your offline-first service worker locally, build the application (using `npm run build`) and run a simple http server from your build directory. After running the build script, `create-react-app` will give instructions for one way to test your production build locally and the [deployment instructions](#deployment) have instructions for using other methods. _Be sure to always use an incognito window to avoid complications with your browser cache._
742742

743743
1. If possible, configure your production environment to serve the generated `service-worker.js` [with HTTP caching disabled](http://stackoverflow.com/questions/38843970/service-worker-javascript-update-frequency-every-24-hours). If that's not possible—[GitHub Pages](#github-pages), for instance, does not allow you to change the default 10 minute HTTP cache lifetime—then be aware that if you visit your production site, and then revisit again before `service-worker.js` has expired from your HTTP cache, you'll continue to get the previously cached assets from the service worker. If you have an immediate need to view your updated production deployment, performing a shift-refresh will temporarily disable the service worker and retrieve all assets from the network.
744744

745-
1. Users aren't always familiar with offline-first web apps. It can be useful to [let the user know](https://developers.google.com/web/fundamentals/instant-and-offline/offline-ux#inform_the_user_when_the_app_is_ready_for_offline_consumption) when the service worker has finished populating your caches (showing a "This web app works offline!" message) and also let them know when the service worker has fetched the latest updates that will be available the next time they load the page (showing a "New content is available; please refresh." message). Showing this messages is currently left as an exercise to the developer, but as a starting point, you can make use of the logic included in [`src/registerServiceWorker.js`](src/registerServiceWorker.js), which demonstrates which service worker lifecycle events to listen for to detect each scenario, and which as a default, just logs appropriate messages to the JavaScript console.
745+
1. Users aren't always familiar with offline-first web apps. It can be useful to [let the user know](https://developers.google.com/web/fundamentals/instant-and-offline/offline-ux#inform_the_user_when_the_app_is_ready_for_offline_consumption) when the service worker has finished populating your caches (showing a "This web app works offline!" message) and also let them know when the service worker has fetched the latest updates that will be available the next time they load the page (showing a "New content is available; please refresh." message). Showing this messages is currently left as an exercise to the developer, but as a starting point, you can make use of the logic included in [`src/serviceWorker.js`](src/serviceWorker.js), which demonstrates which service worker lifecycle events to listen for to detect each scenario, and which as a default, just logs appropriate messages to the JavaScript console.
746746

747747
1. By default, the generated service worker file will not intercept or cache any cross-origin traffic, like HTTP [API requests](#integrating-with-an-api-backend), images, or embeds loaded from a different domain. If you would like to use a runtime caching strategy for those requests, you can [`eject`](#npm-run-eject) and then configure the [`runtimeCaching`](https://github.com/GoogleChrome/sw-precache#runtimecaching-arrayobject) option in the `SWPrecacheWebpackPlugin` section of [`webpack.config.prod.js`](../config/webpack.config.prod.js).
748748

template/src/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import './main.css';
22
import { Elm } from './Main.elm';
3-
import registerServiceWorker from './registerServiceWorker';
3+
import * as serviceWorker from './serviceWorker';
44

55
Elm.Main.init({
66
node: document.getElementById('root')
77
});
88

9-
registerServiceWorker();
9+
// If you want your app to work offline and load faster, you can change
10+
// unregister() to register() below. Note this comes with some pitfalls.
11+
// Learn more about service workers: https://bit.ly/CRA-PWA
12+
serviceWorker.unregister();

template/src/registerServiceWorker.js renamed to template/src/serviceWorker.js

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
// In production, we register a service worker to serve assets from local cache.
1+
// This optional code is used to register a service worker.
2+
// register() is not called by default.
23

34
// This lets the app load faster on subsequent visits in production, and gives
45
// it offline capabilities. However, it also means that developers (and users)
5-
// will only see deployed updates on the "N+1" visit to a page, since previously
6-
// cached resources are updated in the background.
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.
79

8-
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9-
// This link also includes instructions on opting out of this behavior.
10+
// To learn more about the benefits of this model and instructions on how to
11+
// opt-in, read https://bit.ly/CRA-PWA
1012

1113
const isLocalhost = Boolean(
1214
window.location.hostname === 'localhost' ||
@@ -18,50 +20,74 @@ const isLocalhost = Boolean(
1820
)
1921
);
2022

21-
export default function register() {
23+
export function register(config) {
2224
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
2325
// The URL constructor is available in all browsers that support SW.
24-
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
26+
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
2527
if (publicUrl.origin !== window.location.origin) {
2628
// Our service worker won't work if PUBLIC_URL is on a different origin
2729
// from what our page is served on. This might happen if a CDN is used to
28-
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
30+
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
2931
return;
3032
}
3133

3234
window.addEventListener('load', () => {
3335
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
3436

35-
if (!isLocalhost) {
36-
// Is not local host. Just register service worker
37-
registerValidSW(swUrl);
37+
if (isLocalhost) {
38+
// This is running on localhost. Let's check if a service worker still exists or not.
39+
checkValidServiceWorker(swUrl, config);
40+
41+
// Add some additional logging to localhost, pointing developers to the
42+
// service worker/PWA documentation.
43+
navigator.serviceWorker.ready.then(() => {
44+
console.log(
45+
'This web app is being served cache-first by a service ' +
46+
'worker. To learn more, visit https://bit.ly/CRA-PWA'
47+
);
48+
});
3849
} else {
39-
// This is running on localhost. Lets check if a service worker still exists or not.
40-
checkValidServiceWorker(swUrl);
50+
// Is not localhost. Just register service worker
51+
registerValidSW(swUrl, config);
4152
}
4253
});
4354
}
4455
}
4556

46-
function registerValidSW(swUrl) {
57+
function registerValidSW(swUrl, config) {
4758
navigator.serviceWorker
4859
.register(swUrl)
4960
.then(registration => {
5061
registration.onupdatefound = () => {
5162
const installingWorker = registration.installing;
63+
if (installingWorker == null) {
64+
return;
65+
}
5266
installingWorker.onstatechange = () => {
5367
if (installingWorker.state === 'installed') {
5468
if (navigator.serviceWorker.controller) {
55-
// At this point, the old content will have been purged and
56-
// the fresh content will have been added to the cache.
57-
// It's the perfect time to display a "New content is
58-
// available; please refresh." message in your web app.
59-
console.log('New content is available; please refresh.');
69+
// At this point, the updated precached content has been fetched,
70+
// but the previous service worker will still serve the older
71+
// content until all client tabs are closed.
72+
console.log(
73+
'New content is available and will be used when all ' +
74+
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75+
);
76+
77+
// Execute callback
78+
if (config && config.onUpdate) {
79+
config.onUpdate(registration);
80+
}
6081
} else {
6182
// At this point, everything has been precached.
6283
// It's the perfect time to display a
6384
// "Content is cached for offline use." message.
6485
console.log('Content is cached for offline use.');
86+
87+
// Execute callback
88+
if (config && config.onSuccess) {
89+
config.onSuccess(registration);
90+
}
6591
}
6692
}
6793
};
@@ -72,14 +98,15 @@ function registerValidSW(swUrl) {
7298
});
7399
}
74100

75-
function checkValidServiceWorker(swUrl) {
101+
function checkValidServiceWorker(swUrl, config) {
76102
// Check if the service worker can be found. If it can't reload the page.
77103
fetch(swUrl)
78104
.then(response => {
79105
// Ensure service worker exists, and that we really are getting a JS file.
106+
const contentType = response.headers.get('content-type');
80107
if (
81108
response.status === 404 ||
82-
response.headers.get('content-type').indexOf('javascript') === -1
109+
(contentType != null && contentType.indexOf('javascript') === -1)
83110
) {
84111
// No service worker found. Probably a different app. Reload the page.
85112
navigator.serviceWorker.ready.then(registration => {
@@ -89,7 +116,7 @@ function checkValidServiceWorker(swUrl) {
89116
});
90117
} else {
91118
// Service worker found. Proceed as normal.
92-
registerValidSW(swUrl);
119+
registerValidSW(swUrl, config);
93120
}
94121
})
95122
.catch(() => {

0 commit comments

Comments
 (0)