Skip to content

PWA functionality for create-react-app #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 121 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
8289386
sw-precache-webpack-plugin, SW registration, manifest.json
jeffposnick Feb 11, 2017
8ec99b6
Suggest jest-enzyme for simplifying test matchers (#994)
blainekasten Feb 11, 2017
1fe6f55
Add SASS support documentation #1007 (#1008)
tsironis Feb 12, 2017
e8ae98d
Link to new Sass doc
gaearon Feb 12, 2017
071d996
Clarify Less/Sass support
gaearon Feb 12, 2017
f840b4d
Fix `test -e` with wildcard arguments. (#1503)
marcusrbrown Feb 12, 2017
9ffa9e4
Correctly Command in README.md (#1275)
lifez Feb 12, 2017
c7ba130
reactjs/redux#2004 List features beyond ES6 supported by create-react…
jonathanconway Feb 12, 2017
96ebb75
Add a link to supported features
gaearon Feb 12, 2017
ca7fb22
[documentation] how to disable autoprefix feature (#1320)
Feb 12, 2017
6c85568
Added link to Azure deployment tutorial (#1338)
tpetrina Feb 12, 2017
75088ab
Documentation + a few SW tweaks.
jeffposnick Feb 12, 2017
434e858
Add useful link to react-scripts (#1495)
pd4d10 Feb 12, 2017
411347f
Update language support wording to ES2017
Timer Feb 12, 2017
c9bc6ce
Tweak syntax doc (#1539)
gaearon Feb 12, 2017
915b130
Make node version check more robust in e2e.sh (#1295)
pugnascotia Feb 13, 2017
ce0d6ee
update CSS preprocessor instructions (#1543)
Feb 13, 2017
9df3104
Revert "Don't run CI on Node 0.10" (#1547)
Timer Feb 13, 2017
745d341
Use Yarn latest in e2e (#1534)
gaearon Feb 15, 2017
fc49946
Add support for dynamic import & disable require.ensure (#1538)
Timer Feb 15, 2017
1d5a277
Enable `watchContentBase` for webpack-dev-server (#1546)
SpaceK33z Feb 15, 2017
9c33f60
Re-enable transform-react-constant-elements (#1552)
existentialism Feb 15, 2017
6d22a78
modified documentation for setting up jest-enzyme (#1562)
kiranps Feb 15, 2017
b0bc46e
Use https in link to Ignoring files at Github (#1561)
Feb 15, 2017
075e729
add --recursive to sass watch script (#1564)
Feb 15, 2017
5e65f0d
Mention Windows support explicitly
gaearon Feb 15, 2017
c8cbbd0
Reorder
gaearon Feb 16, 2017
1fc1d82
Update README.md (#1573)
mkermani144 Feb 16, 2017
e9493a2
MacOS => macOS
gaearon Feb 16, 2017
41632fb
Revert "Bump babel deps and re-enable transform-react-constant-elemen…
gaearon Feb 16, 2017
bfed215
Added an unregister method, too, just in case.
jeffposnick Feb 16, 2017
2835105
More info for the READMEs.
jeffposnick Feb 16, 2017
2dc418b
Add minify to SWPrecacheWebpackPlugin config
goldhand Feb 17, 2017
21d14bb
Fix SWPrecacheWebpackPlugin typo
goldhand Feb 17, 2017
a681e91
Fix file references in READMEmd
ianschmitz Feb 17, 2017
a9fb906
Add instructions for testing service-worker locally
goldhand Feb 17, 2017
bee4ece
Switch from Neo to Neutrino (#1576)
eliperelman Feb 17, 2017
dd9ec7b
fixes #1584 PORT env variable not always an integer (#1585)
matoilic Feb 18, 2017
1aa4b2b
babel-preset: remove babel-plugin-transform-es2015-parameters (#1598)
christophehurpeau Feb 21, 2017
2a8535b
Add note for using CHOKIDAR_USEPOLLING in virtual machines to enable …
AJamesPhillips Feb 22, 2017
d945370
Allow --scripts-version to be a git url (#1570)
tomconroy Feb 23, 2017
a82896c
Install react, react-dom, and react-scripts at the same time (#1253)
n3tr Feb 23, 2017
21fe19a
Bump deps for webpack 2 compat (#1621)
Timer Feb 23, 2017
7be0f4d
add a comment about NODE_ENV value set to 'production' during build s…
mderazon Feb 24, 2017
646690b
Update flow configuration documentation (#1518)
SBrown52 Feb 24, 2017
92a0680
Add note about when to import bootstrap CSS. (#1618)
joewoodhouse Feb 24, 2017
67d0d49
Document Sass imports
gaearon Feb 24, 2017
bec009c
Fix workflow if react-scripts package is linked via npm-link (#1356)
tuchk4 Feb 24, 2017
577c4e8
Document debugging in the browser. (#1540)
bondz Feb 24, 2017
e14e003
Link to "Debugging in the Editor"
gaearon Feb 24, 2017
0ef9e80
(feat): add webpack validation error logging (#1596)
johann-sonntagbauer Feb 24, 2017
09cfcde
Add lint rule to disallow require.ensure and System.import (#1536)
tharakawj Feb 24, 2017
c3240a1
Adding link to “Customizing” create-react-app (#1121)
Feb 24, 2017
1c0851d
Update index.js (#1603)
driquelme Feb 24, 2017
d6a83aa
Remove .bin files defined at react-scripts/package.json after eject …
tuchk4 Feb 24, 2017
41d1469
Bump `recursive-readdir`. (#1560)
wtgtybhertgeghgtwtg Feb 24, 2017
dd801e2
Disallow event global variable with no-restricted-globals rule (#1530…
vfil Feb 24, 2017
c8d9c47
Added a how-to on react-snapshot (#1577)
superhighfives Feb 24, 2017
53db95a
NPM version check for tip (#1193)
rangle-mobinni Feb 24, 2017
8d41328
Enable eslint caching in development (#1578)
viankakrisna Feb 24, 2017
925ab72
Use real build path name in build output (#1478)
chyipin Feb 24, 2017
5155797
adding a note on how to resolve "Could not find a required file." dep…
Feb 24, 2017
b609ac9
Use posix paths for Jest config during eject (#1635)
Timer Feb 24, 2017
dbf17fd
Setting a dynamic port value for the pushstate-server URL text (#1628)
mattccrampton Feb 24, 2017
3289c32
Fix up broken line
gaearon Feb 24, 2017
2288ddf
Support & test import() for non-bundled code (#1615)
Timer Feb 25, 2017
6876c40
Gracefully handle initial installation error (#1512)
chitchu Feb 25, 2017
f3d8fff
Published 0.9.1 at 9e2624f332eea9032051dceb95eebfad5c158561
Timer Feb 26, 2017
e1aaf39
Add changelog for 0.9.1
Timer Feb 26, 2017
f68cc67
Update changelog
Timer Feb 26, 2017
253c1e0
Add a note about known issue
gaearon Feb 26, 2017
2f6fac9
Fix npm test on Windows (#1647)
gaearon Feb 26, 2017
fbae44a
Add 0.9.2 changelog
gaearon Feb 26, 2017
ba5da93
0.9.2
gaearon Feb 26, 2017
e1e28d9
Merge changelogs
gaearon Feb 26, 2017
68e9bb9
Format differently
gaearon Feb 26, 2017
432ba82
Set Chrome userDataDir to be under .vscode folder (#1657)
ryansully Feb 27, 2017
d0695f7
Fix e2e when used with cold cache (#1667)
Timer Feb 27, 2017
a1858c7
Fix e2e-simple (cont.)
Timer Feb 27, 2017
a3a223a
Add appveyor.yml (#1648)
Timer Feb 27, 2017
2d93ae1
fix react dependency versions during initial install (#1669)
johann-sonntagbauer Feb 28, 2017
715968e
Remove Windows 0.10 simple test
Timer Feb 28, 2017
c51a611
add project name validation (#1662)
johann-sonntagbauer Feb 28, 2017
3509dcd
fix project cleanup on windows (#1675)
johann-sonntagbauer Feb 28, 2017
7c899fc
Revert "Enable eslint caching in development" (#1665)
gaearon Feb 28, 2017
2b824d8
add X-FORWARDED headers for proxy requests (#1677)
johann-sonntagbauer Feb 28, 2017
bf948bf
Use offline cached version with yarn when it's possible (#1423)
voxsim Feb 28, 2017
15e1ec2
Add 0.9.3 changelog (#1683)
gaearon Feb 28, 2017
ee3b788
Add "migrating" section for 0.9.3
gaearon Feb 28, 2017
a85ae1d
False expression should not be in dependencies
Timer Feb 28, 2017
10a8dc6
Published 0.9.3 from 0.9.x
gaearon Feb 28, 2017
342867e
appveyor: Build all branches
Timer Mar 1, 2017
1a838dc
Published CLI from 0.9.x
Timer Feb 28, 2017
60ba9f2
Suggest CRA 1.2.1 in changelog
gaearon Mar 1, 2017
af6a0ff
Fixed missing flag in first preprocess command (#1687)
mklemme Mar 1, 2017
43139bc
Re-enable e2e-install directory test
Timer Mar 1, 2017
404c354
Suggest to use .env for enabling polling mode (#1698)
gaearon Mar 2, 2017
45d1d24
Update extract-text-webpack-plugin to latest (#1700)
SimenB Mar 2, 2017
db64278
Diagnostic code (#1695)
tgig Mar 2, 2017
c7a9dae
Fix Jest tests for Cygwin
Timer Mar 3, 2017
1cdb4cd
Merge pull request #2 from goldhand/pwa
jeffposnick Mar 3, 2017
4e3ede4
Review feedback
jeffposnick Mar 3, 2017
59cab8f
Improve reliability of port hint. (#1696)
chrisdrackett Mar 3, 2017
b88d665
Modularise scripts (#1433)
djgrant Mar 4, 2017
72695a1
Remove unneeded `url` lib (#1715)
pd4d10 Mar 4, 2017
b421ed9
pin and bump lerna (#1688)
viankakrisna Mar 4, 2017
8951fbe
Lerna 2.0.0-beta.38 expects packages entry
Timer Mar 4, 2017
443ca23
Add docs for apache's client side routing setting (#1717)
viankakrisna Mar 5, 2017
3fe8289
Update now.sh deployment instructions. (#1710)
replaid Mar 5, 2017
19a4672
Add support for ignoreRestSiblings in no-unused-vars (#1705)
chrisdrackett Mar 5, 2017
4ec5af3
add double quotes to escape spaces in paths in e2e (#1707)
viankakrisna Mar 5, 2017
ae61bf6
Create appveyor.cleanup-cache.txt
gaearon Mar 5, 2017
9d8096e
Link Appveyor caches to appveyor.cleanup-cache.txt
gaearon Mar 5, 2017
23f85d3
Trigger AppVeyor cache cleanup
gaearon Mar 5, 2017
d07accb
Fix openBrowser() when BROWSER=open on macOS (#1690)
bpierre Mar 5, 2017
5414cff
Create empty package.json in e2e test (#1401) (#1402)
matoilic Mar 5, 2017
01c3597
Skip AppVeyor CI builds for Markdown changes (#1723)
gaearon Mar 5, 2017
ed9eeeb
Don't use ES6 in a file that should run on Node 4 (#1724)
gaearon Mar 5, 2017
13f26e3
Bump jsx-a11y version (#1542)
bondz Mar 5, 2017
86d590d
Some additional PWA metadata
jeffposnick Mar 5, 2017
0640a20
Merge remote-tracking branch 'upstream/master' into pwa
jeffposnick Mar 5, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ Builds the app for production to the `build` folder.<br>
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.<br>
Your app is ready to be deployed!
A [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) using an [offline-first caching strategy](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network) is automatically generated.<br>
Your ([progressive web](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app)) app is ready to be deployed!

## User Guide

Expand Down Expand Up @@ -151,6 +152,7 @@ Please refer to the [User Guide](https://github.com/facebookincubator/create-rea
* Import CSS and image files directly from JavaScript.
* Autoprefixed CSS, so you don’t need `-webkit` or other prefixes.
* A `build` script to bundle JS, CSS, and images for production, with sourcemaps.
* An offline-first [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) and a [web app manifest](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/), meeting all the [Progressive Web App](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) criteria.

**The feature set is intentionally limited**. It doesn’t support advanced features such as server rendering or CSS modules. The tool is also **non-configurable** because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything.

Expand Down
7 changes: 7 additions & 0 deletions packages/react-scripts/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var url = require('url');
var paths = require('./paths');
var getClientEnvironment = require('./env');
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

// @remove-on-eject-begin
// `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174
Expand Down Expand Up @@ -273,6 +274,12 @@ module.exports = {
// having to parse `index.html`.
new ManifestPlugin({
fileName: 'asset-manifest.json'
}),
new SWPrecacheWebpackPlugin({
dontCacheBustUrlsMatching: /\.\w{8}\./,
filename: 'service-worker.js',
navigateFallback: publicUrl + '/index.html',
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/]
})
],
// Some libraries import Node modules but don't use them in the browser.
Expand Down
1 change: 1 addition & 0 deletions packages/react-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"recursive-readdir": "2.1.0",
"strip-ansi": "3.0.1",
"style-loader": "0.13.1",
"sw-precache-webpack-plugin": "^0.9.0",
"url-loader": "0.5.7",
"webpack": "2.2.1",
"webpack-dev-server": "2.3.0",
Expand Down
86 changes: 85 additions & 1 deletion packages/react-scripts/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,82 @@ Learn more about React Storybook:

## Making a Progressive Web App

You can turn your React app into a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) by following the steps in [this repository](https://github.com/jeffposnick/create-react-pwa).
By default, the production build is a fully functional, offline-first
[Progressive Web App](https://developers.google.com/web/progressive-web-apps/).

The [`sw-precache-webpack-plugin`](https://github.com/goldhand/sw-precache-webpack-plugin)
is integrated into [`webpack.config.prod.js`](../config/webpack.config.prod.js),
and it will take care of generating a service worker file that will automatically
precache all of your local assets and keep them up to date as you deploy updates.
The service worker will use a [cache-first strategy](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network)
for handling all requests for local assets, including the initial HTML, ensuring
that you web app is reliably fast, even on a slow or unreliable network.

It includes a [web app manifest](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/),
located at [`public/manifest.json`](public/manifest.json), that you might want
to customize with metadata specific to your web application, such as its name
and branding colors.

If you would prefer not to enable service workers prior to your initial
production deployment, then remove the call to `serviceWorkerRegistration.register()`
from [`src/index.js`](src/index.js).

If you had previously enabled service workers in your production deployment and
have decided that you would like to disable them for all your existing users,
you can swap out the call to `serviceWorkerRegistration.register()` in
[`src/index.js`](src/index.js) with a call to `serviceWorkerRegistration.unregister()`.
After the user visits a page that has `serviceWorkerRegistration.unregister()`,
the service worker will be uninstalled.

### Offline-First Considerations

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.

1. Service workers are [not currently supported](https://jakearchibald.github.io/isserviceworkerready/)
in all web browsers. Service worker registration [won't be attempted](src/register-service-worker.js)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe src/register-service-worker.js should be src/service-worker-registration.js

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in PR #3

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged @ianschmitz commit from pr #3 into pr #2 to avoid merge conflicts (I want to suggest other changes to the README)

on browsers that lack support.

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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest adding instructions for testing locally (incase they want to despite your warning. I have no doubt some people will).
I added the instructions in pr #2 They are found in this commit: goldhand@a9fb906

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged.

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.

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/register-service-worker.js`](src/register-service-worker.js), which

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. src/register-service-worker.js should be src/service-worker-registration.js

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in PR #3

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merged into #2

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.

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 `SWPrecachePlugin` section of
[`webpack.config.prod.js`](../config/webpack.config.prod.js).

## Deployment

Expand Down Expand Up @@ -1096,6 +1171,15 @@ This is because when there is a fresh page load for a `/todos/42`, the server lo

Now requests to `/todos/42` will be handled correctly both in development and in production.

On a production build, and in a browser that supports [service workers](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers),
the service worker will automatically handle all navigation requests, like for
`/todos/42`, by serving the cached copy of your `index.html`. This
service worker navigation routing can be configured or disabled by
[`eject`ing](#npm-run-eject) and then modifying the
[`navigateFallback`](https://github.com/GoogleChrome/sw-precache#navigatefallback-string)
and [`navigateFallbackWhitelist`](https://github.com/GoogleChrome/sw-precache#navigatefallbackwhitelist-arrayregexp)
options of the `SWPreachePlugin` [configuration](../config/webpack.config.prod.js).

### Building for Relative Paths

By default, Create React App produces a build assuming your app is hosted at the server root.<br>
Expand Down
1 change: 1 addition & 0 deletions packages/react-scripts/template/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
Expand Down
13 changes: 13 additions & 0 deletions packages/react-scripts/template/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"short_name": "React App",
"name": "React App",
"icons": [
{
"src": "favicon.ico",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "./",
"display": "standalone"
}
3 changes: 3 additions & 0 deletions packages/react-scripts/template/src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorkerRegistration from './service-worker-registration';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are importing both register and unregister methods so they can easily unregister the SW if its in production and has already been registered by users. I think this is an unlikely situation, considering this is the beginning of a react app.
IMHO it would be better to export default register and then just do import registerSW from './service-worker-registration' and registerSW();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that these proposed changes are not in any pr (everything else is though)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

import './index.css';

ReactDOM.render(
<App />,
document.getElementById('root')
);

serviceWorkerRegistration.register();
38 changes: 38 additions & 0 deletions packages/react-scripts/template/src/service-worker-registration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export function register() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export default function register() here as mentioned in previous comment

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
Copy link

@ryansully ryansully Feb 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without an accompanying unit test (which would likely require some heavy-duty mocking), the code including and past this line has a negative effect on my project's coverage report. I left a comment on an upstream issue (facebook#1299 (comment)) regarding having the ability for Jest to ignore files such as this.

EDIT: There is another issue, facebook#1455, that directly addresses this concern.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... I don't know much about Jest, and have yet to find a good way to create a mock environment for testing service worker-specific code outside of a real browser.

I'm hoping that some resolution would come out of those issues you reference. Is there anything that you'd suggest adding to this PR to work around it in the meantime?

window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
navigator.serviceWorker.register(swUrl).then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
}).catch(error => {
console.error('Error during service worker registration:', error);
});
});
}
}

export function unregister() {
if ('serviceWorker' in navigator) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for production environment (process.env.NODE_ENV === 'production') also here, to be consistent with the other function.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm providing unregister() as a quick way for a developer to explicitly invoke to fix an "Oops! I really didn't mean to register a service worker for that origin!" scenario.

I'm thinking that if someone calls it, then they really want any registered service workers to be removed, even if they don't have NODE_ENV properly configured.

The code is also effectively a no-op if there is no service worker registered (navigator.serviceWorker.ready will never fulfill), so I'm not worried about side effects of running it in development mode.

navigator.serviceWorker.ready.then(function(registration) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the callback function to arrow function syntax, for the sake of consistency with the rest of the file.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

registration.unregister();
});
}
}