facebook / create-react-app

Set up a modern web app by running one command.

Home Page:https://create-react-app.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why was service worker merged into create react app?

jantimon opened this issue · comments

I use create create app for teaching and I don't see the benefit in making stuff more complicated with adding so much advanced boilerplate code.

You probably know that service worker won't work on any iOS device (20% - 25% of all your users) and this is not about to change soon (maybe never).

Adding service workers by default is about to create very different experiences and bug behaviour depending on the device. It also makes it way more complicated to get a create react app to work offline for all platforms.

Please don't turn cra into something like a Windows98 computer where you had to remove AOL and other preinstalled stuff before being able to be productive.

commented

I see your point but I don't agree removing a single line from src/index.js is a big deal (and that's all you need to do to opt out). If you can clarify what exactly makes your life harder (in practical terms, e.g. a specific scenario that is confusing) maybe we can make it better via other means.

While iOS is lagging behind, there is more momentum than ever behind using service workers for webapps (basically everywhere except iOS), and we’re going to stick with this for a while. If people don’t find it useful and most of the feedback we get repeats yours, we will remove it. So far the reception has been positive, but it’s hard to say until we live with this change for at least several months.

If the tool was called “create react website” then I’d agree with you, but people expect more responsiveness from apps, and precaching helps bridge that gap. We’ll see if it works out or not.

This is an excellent response @gaearon. I was initially quite surprised to see it there (I found this thread searching for effectively the exact title of the issue!), but my original reaction was largely because I still don't feel super comfortable using SWs. I know plenty about them, but I don't feel like I really understand all the potential traps—I don't know what I don't know, you know? ;)

But the momentum behind PWAs is undeniable, and if people's first concrete introduction to SWs is that their CRA-ed apps are precached (and if they don't want it, disabling it is a one-liner) then this sounds like a super smart addition 👌

We've used PWA and service workers for museum mobile webapps for a year and it has been great. I think encouraging their use is absolutely what we should be doing.

commented

Here is example of a person wasting hours (and even deleting Node) being confused by the cache. I'm still on board with service workers but there is a clear usability/discoverability issue here.

@jeffposnick Do you have thoughts on how to make troubleshooting these scenarios less maddening? We can’t keep this as a default if people are going to have experiences like this.

https://www.reddit.com/r/javascript/comments/6dwbig/react_running_even_after_everything_removed/

commented

One possible solution is to show "The app was served from [offline cache]" right in the default App.js when it happens. This would make the feature more discoverable. Can we detect this?

Why not just make it an option (default off)? I doubt many newbies are going to absolutely need service workers and experience devs who want to use CRA to start developing new projects quickly will know how to have it easily create their app with SW support. Seems like a win:win to me.

One possible solution is to show "The app was served from [offline cache]" right in the default App.js when it happens. This would make the feature more discoverable. Can we detect this?

@gaearon it's possible, I came up with a solution a while ago: lukechilds/onionite@416ccb0#diff-7a7a9fab4ca3224cad19254b6aba0be3R60

It's pretty ugly though, I'm sure there's a cleaner way.

You can demo that commit by viewing https://onionite.now.sh, then disable network and view a SW cached page. It should say something like *There seems to be an issue connecting to the server. This data is cached from Fri Jan 13 2017 15:00:38 GMT+0700 (ICT) at the top of the page.

Service workers are intentionally super sticky, so even if you remove the one line if you ran the app before it's now there, and you need to write code to remove it from you browser (or know where the knobs are in the chrome dev tools).

Either way tho you are immediately asking folk to learn/understand an advanced low level api before even starting to build an app.

I was also confused by that file and I'm not a total newbie. Maybe it would be helpful to include a description on how to opt out, instead of directing users to a PWA section of the readme?

commented

The only thing I'm asking in that thread is that we try to focus on the solutions instead of dismissing the idea outright. If the problem is "Chrome toggles are tucked away too far", Chrome folks are invested in solving this and we can influence that. If the problem is lack of a comment we can add it. Et cetera. Let's just entertain the thought that it might be possible to make this a good default, and then see what are the paper cuts, and how to go about them.

@shime I think the README is a perfect place for this information. There are no comments for importing CSS files inside a .js file and that itself is a whole new concept to some people.

Removing the Service Worker file isn't too much hard work though. @gaearon is right - we should see how PWA's progress and it's great there's built in support for this functionality.

Sorry I'm not trying to be dismissive :) I don't think tho this is really just a UX issue. Having the SW register script causes odd issues for folks that aren't familiar with it while also offering minimal value in the PWA arena out of the box, because the content of the SW is deeply app specific and the caching rules ultra dependent on the dev understanding the cache pattern that suits each particular request, resource etc. Otherwise you get frustration and issues.

That said from a DX perspective I've almost always want the SW off in development unless I'm specifically working on offline flows or fallback. In which case tho it's important to run in DEV mode otherwise it's too much time between builds to tweak and troubleshoot. This ends up being an issue mostly with chrome burying the SW toggles in the application tab

The other issue here is that just preaching assets is troublesome, some assets I don't want to cache while others I want a ttl or something. Webpack makes this harder because with hashes you don't know the name of assets so you can even adjust or tweak the rules there (does precache plugin even allow that). Generally I've had good success with webpack-service-worker-plugin as it uses the manifest to make assets available in the service worker, and runs it through webpack so you can still use Babel, etc in the file

  • The SW behaviour takes time to understand until you super comfortable with SW behaviour, work in an incognito browser window, that will help your browser forget about all SW on that localhost port and start fresh always.

  • SW API is powerful and we can programmatically do a lot of things, opt-out and clean everything is doable really easy. Knowing what's cached is easy, we just need to listen and learn from Devs what issues are they facing so we ship the right and useful SW Dev util.

Example of a nice experiment I like to clean SW and local cache and has useful application on dev:

https://gist.github.com/gauntface/38fcbd5495455c06f45d2b674f57be83

SW is more lovely than what it seem to be, bit of education about it and right helpers will keep experience great for devs and users!

If there's a standard way of displaying overlays/toasts in c-r-a, then methods of the Service Worker API can be used to notify developers what's going on.

There's a very basic placeholder in the registration script that logs something to the JS Console, but that's (intentionally) not in-your-face.

Code like

if ('serviceWorker' in navigator &&
    process.env.NODE_ENV !== 'production' &&
    navigator.serviceWorker.controller) {
  // Display some sort of message about the page being loaded by the service worker.
} 

could be used to further inform developers while outside of the production environment.

The sw-precache-webpack-plugin does support a blacklist of assets that shouldn't be precached, but that involves modifying the Webpack configuration, which in turn implies an eject.

The majority of the PR to add in PWA support consisted of explanatory text in the README in an attempt to explain various implications of using a cache-first strategy, but this is obviously a big change in the development and deployment model. Getting information in front of developers via overlays and contextual messages is definitely a good idea if there's a standard way of doing it.

Either way tho you are immediately asking folk to learn/understand an advanced low level api before even starting to build an app.

This is valuable feedback. Let’s address it. There are a few different places we can add proactive developer education that can help.

Toasts - a visible, teachable moment

Across a few different boilerplates, we’ve found toasts to be a low-friction way to communicate to both users and developers that a page is offline capable. Here are some examples:

If you also try out Voice Memos or SVGOMG you'll see that these toasts have a finite lifetime and are only shown for a few seconds.

For a project like create-react-app, such a toast could even link out the text in the toast to the CRA Service Worker documentation and we could use that as another teaching moment to help beginners learn what Service Workers are giving them.

I'll leave it to the more savvy designers on CRA to suggest ideas, but here's just one take on it:

This is also helpful for a few reasons:

  • Gives the beginner that wants to keep PWA/offline support a way to expand their knowledge of how to use it effectively
  • Gives the developer unsure about using SW instructions on how to opt-out/disable it

Sometimes folks feel a toast requires bringing in a whole UI library. It can be achieved in just a few lines of code independently and if there's interest we can work on a PR for what this would look like.

Runtime Error Message overlay/Better console messages

screen shot 2017-05-29 at 9 50 59 am

Inform developers that the page is offline capable and provide some short text on where to learn more about CRA's support for it and where they can learn more about debugging Service Workers (this codelab has been great) . I'm unsure if the runtime overlay is strictly only meant to be used for DEV development messages, but that could be another option.

We can be strategic about linking out to answers for the most common questions here regardless of whether it's shown in an overlay or the console.

For SW specifically, anything we can do to teach devs about the existence of the Application panel is good. A lot of the time you'll just use it to verify: 1) your offline support is indeed working as expected, 2) you want to be extra sure the freshest content is being served, so 'Clear Storage' is your friend.

React Developer Tools

We could define an additional check as part of the current production messaging (or somewhere inside the React DevTools panel itself) a way to inform developers that their page is offline capable and was served using Service Workers.

screen shot 2017-05-29 at 9 38 30 am

An additional check/entry here could be "This page appears to be offline capable. Learn more about this" that links up to the CRA SW documentation.

Chrome DevTools

This is a longer-term change, but I want to lean on the team on our side to provide very visible indicators that a Service Worker is active on the page. I'm unsure if we accomplish this using a butter-bar, or our own overlays, but it's a common enough request that I think we should do something better to inform beginners that offline support has kicked in. I'll talk to the team and update this thread with any ideas we brainstorm.

commented

This is a longer-term change, but I want to lean on the team on our side to provide very visible indicators that a Service Worker is active on the page. I'm unsure if we accomplish this using a butter-bar, or our own overlays, but it's a common enough request that I think we should do something better to inform beginners that offline support has kicked in.

This sounds like the best way to go about it, and will benefit any setups (not just CRA).

If you want PWA approach to gain traction, it is important to teach developers to trust this feature. Any time I use a tool that caches something too aggressively, a single mistake or misunderstanding is enough to forever destroy my trust and learn to either wipe away or disable the cache. It’s not very rational, but it’s how human mind works: once burned, you’ll avoid the feature as much as you can.

Now that service workers are going mainstream, it is important not to make people‘s first experiences bad. Otherwise the trust will never be recovered, and even if the idea is good, the execution will botch their adoption.

I think it's very important that @gaearon didn't dismiss the problem on reddit and turned this into an opportunity. SW are great, but there was a whole talk about how dangerous it can be at JSConf. (https://www.youtube.com/watch?v=CPP9ew4Co0M)

Possibly as a first step, SW may not work at all in development mode. Offline indicators should also be a part of the app, but design is challenging.

commented

Just to make it clear, SWs are not enabled in development mode in CRA.

My bad, after reading the reddit post I assumed it was. Will be more careful next time. :)

We could turn service workers off by default for localhost?

As the only real reason to have them on for localhost is if you were actually testing SW and therefore you would hopefully be able to find the how to turn them on for localhost again.

Thanks again for create-react-app, I use it all the time.

The solution I think is to carefully document new features that are added to CRA. Something like these points in the doc would have been very helpful.

SERVICE WORKERS have been added to CRA: (required reading)

  • DANGER: unless you understand and want to use service workers you MUST edit index.js and remove the call to "registerServiceWorker.js()" . While service workers are NOT included by default in development mode ( aka running "npm run start", they ARE are included by default during the build process! (npm run build)
  • WHAT CAN GO WRONG: if you can't seem to stop a server from running by normal methods, or if it appears that the browser cache is not being cleared the normal way.
  • FIX: clearing the browser cache does NOT clear the service worker. On Chrome, enable developer tools, select the application tab and unregister the service worker. On CANARY click "show all" and then select the service worker.
  • RECOMMENDATION: service workers are significant advance and are included for that reason. Several good resources are available here, here and here

Edit: just to be clear, I think it is great service workers were added! I just wish I had been warned that I didn't know what I didn't know.

I'm excited about service workers and glad to see CRA integrating them. But I'm not sure the current scaffolding is rich enough to turn on by default. Why not just have the SW commented out by default in index.js and making it opt in until the legit issues have been better addressed and more education can be done?

Here's one problem my app ran into when I added SWs a couple months ago. I have a real-time app which really requires everyone using it together at the same time to be on the same version. Historically new releases were never a problem. When I added SWs because of the need for every return user to hard reset to update the cache, some people were on, say, 4.0 and some on 5.0. This broke both user expectations and the app itself.

This was easy to catch in QA, but some problems are (1) it's not something that should be worried about in, say, an early version of an app, (2) it's one more thing, and a low level thing at that, for beginners to account for, (3) a good solution is not obvious, (4) the solution is probably generic across apps and thus should be at least documented in CRA and probably with some overridable toast handling.

Again, I'm grateful for the work everyone is doing integrating SWs into CRA, just a case to think about.

I just ran into another SW issue.

I was using serve to run my build locally on localhost:5000, then I used serve again to host a different site on localhost:5000. But because of the service worker, i received the old site instead of the new one.

If I didn't already know about CRA, SW and this thread, I would have teared my hair out trying to figure that one out.

Which takes me back to the idea of not having service workers running for anything on localhost, or even turning off by default might be a good option for now.

commented

I was using serve to run my build locally on localhost:5000, then I used serve again to host a different site on localhost:5000. But because of the service worker, i received the old site instead of the new one.

I also got a similar issue a few times and found it annoying and confusing.

@jeffposnick @addyosmani

Do you see any specific solution to this, from developer experience point of view? It’s not even about toasts and indicating an app is offline and cached—it’s about different apps usually running on the same port locally one after another.

Which takes me back to the idea of not having service workers running for anything on localhost

I’m worried this will lead to extreme confusion when the app behaves differently in production.

I thought we already handled that case once you refresh once (with our noop service worker); I'm not sure if it gets much better than that.

commented

That’s for running different production apps.
For example if I do npm run build for different React apps and then attempt to serve them.

There are a few different scenarios related to localhost development/staging:

You exclusively use npm start for development, and serve for staging

localhost:3000 should not end up with any SW registered, and development will continue as before. localhost:5000 will end up with the SW registered, and the cache-first strategy means that if you switch from one project to another, you'll see the old project the next time you visit localhost:5000—meanwhile the new project will be cached in the background, and then the next time you visit after that, you'll see the new project's output. (I'm assuming that if @ro-savage had known to reload localhost:5000, they would have seen the content they expected—if not, that's a bug I would definitely like to follow up on.)

Currently, when this happens, there should be a message logged in the JS console explaining that new content is available, but this only visible if you know where to look.

An overlay or some sort of other notification can help here in terms of letting developers know that there's new content that was downloaded in the background. This might be on by default for localhost and perhaps optional for a real server (in case the developer wants to show their own UI elements instead.)

I'm really not one for crafting React UX elements, but I think all the right hooks are there to trigger the display—it's just a question of having a standard way of showing it (other than console.log()).

I agree that disabling SW entirely on localhost would not be ideal, because being able to confirm the SW behavior prior to deployment is important.

You inadvertently started a web server running a production build on localhost:3000, and then you use npm start

This scenario should be addressed by this PR.

@jeffposnick - The console.log() message only seems to come up if the page is another create-react-app.

If you are running a non CRA site/app on the same localhost:port not only won't you get the message but refreshing doesn't load the new page. You actually have to de-register the service worker manually to see the correct content.

Is there a way within the client app itself we can give the service worker a permanent ID and everytime it starts, it checks to see if 1) there is a service worker 2) it has the same ID?

If it gets no response, check if it gets a 200 ok from the server. On 200 ok, force refresh. On timeout do nothing.

If it gets a response with a different ID, force refresh.

I wasn't able to find an id field for service workers (at least not one that worked).

But if we gave the service-worker.js a unique ID generated when the project was first created we could do something like this.

export default function register() {
  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      // this would become service-work-id.js
      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
      if (!navigator.serviceWorker.controller) {
        // No service worker yet
        registerServiceWorker(swUrl)
      } else {
        fetch(swUrl).then(res => {
          // Check to see if the SW URL is valid
          if (res.ok) {
            // Matches. All good. Continue with registering SW
            registerServiceWorker(swUrl)
          } else {
            // SW URL was invalid.
            fetch(`${window.location.protocol}//${window.location.host}`).then(res2 => {
              // Just check if online
              if (res2.ok) {
                // Unregister and refresh page
                unregister()
                window.location.reload(true)
              } else {
                console.log('Offline. Using cached copy')
              }
            })
          }
        })
      }
    })
  }
}

function registerServiceWorker(url) {
  navigator.serviceWorker
           .register(url)
           .then(registration => {
             console.log('reg.scope', registration.scope)
             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.log('No service worker found')
             console.error('Error during service worker registration:', error)
           })
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.unregister()
    })
  }
}

@ro-savage The idea of forcing a reload using a deterministic hint is an interesting idea. Have you tested out the pattern above to verify it addresses the non-CRA site being served on the same port as a cached CRA site issue?

An addition I was going to add to @jeffposnick's last list was we could explore port randomization for serving up the production build. I've used this in some of my own local boilerplates.

This would be a naive way of limiting the chances of another site being served on the same port as a previously cached CRA app. However, this may be less desirable than some of the other alternatives we could explore.

@addyosmani - Tested and working locally on mine both with multiple CRAs and with non-CRA sites all on the same port.

I'll put in a PR for people to play with.

I am not entirely sure about what edge cases might exist.

Rather than port randomisation, could we generate hashed local addresses like http://my-app-name-hash1a2b3c4d5e.dev a bit like how Pow works?

Alternatively, http://my-app-name-hash1a2b3c4d5e.localhost:5000 could work too, and wouldn't even require any changes to serve, but it's actually just being keyed off the port so if you accidentally load up http://localhost:5000 you'd hit the same problem.

Of course, this is all assuming there's no added weirdness with SWs and subdomains...

Oo that's neat, tho I think the problem with that approach might be that SW require https unless it's on localhost

Ah yes of course. Potentially then serve --port 5000 --subdomain my-app-name-hash1a2b3c4d5e could return a 301 to redirect http://localhost:5000 to the subdomain, so the SW is never installed except for a URL tied to that app & revision.

Added #2438 which is an attempted to invalidate SW cache on both different CRA apps and non-CRA apps when hosted on the same domain+port.

While we could tell the user to use serve and give them the full command to use. It feels like a work-around rather than a fix. It doesn't solve the issue if they use something else to host locally, or if they try to serve it later and don't remain the correct --subdomain my-app-name-hash1a2b3c4d5e, etc. Same goes for random ports.

CRA 'should just work'.

@gaearon - What are you feeling about disabling PWA until the issues are solved?

Currently CRA is potentially breaking other apps and projects locally for people and knowing both that its caused by SW and how to unregistered a service worker is quiet confusing.

Two cents: with a solution like #2438 providing a workaround, why don't we try landing something we acknowledge decreases the chances of someone tripping up on SW support without disabling it? We could keep iterating on a better solution here in the mean time.

Continuous feedback on the DX gaps from SW being a default for production forces us to address any pain points sooner rather than later.

Appears to only be affecting Firebase. Will investigate. now and surge both seem to refresh fine.

Deploying changes with serve, now, surge and firebase. Firebase failing to refresh the page with SW, rest are working fine.

Approximately 3 minutes
https://www.youtube.com/watch?v=oYy-WqkgS1Q

Full details see: #2440

I am getting returned an old index.html and bundles from the service workers.

Going to site in chrome, which has been visited previously before latest deploy

chrome-service-workers

Same site in firefox, which hasn't visited previously
firefox-service-workers

Notice the different bundle names. (DevTools open which disabled cache checked + index.html is served with cache-control 0).

On top of that, I can't unregister users because when I update the bundle with the unregister() instead of registerServiceWorker() the users never receive the updated bundle. Meaning the only way it for the user to manually delete the service worker?

Thanks to all to lead this question in an open and constructive discussion.

I understand that google uses a lot of dollars and pressure to push service worker into the web so Apple is forced to adapt.
And please don't get me wrong ServiceWorker is an awesome technology and hopefully Apple will abandon their plan of becoming the company which builds the most hated mobile browser.

But I believe it's not about the technology.
For me create-react-app was the perfect start point which had one main goal:
Get all the road blocks out of the way and get excited about react!

  • No local webserver config.
  • No bundler config.
  • No typings in the code.
  • No scss.

Even a less experienced developers gets his/her first react app running without frustration of all the magic which happens behind the scenes.

For me ServiceWorker is just a technology like TypeScript/Flow or Sass.
On the one hand they all add a lot of advantages but on the other hand they add complexity which comes with a lot of possible frustration (as you read in the comments above).

Please keep it simple and don't fight googles fight for service worker here in this project.

As I needed to show UI elements when offline ready, in offline mode etc. so I converted the registerServiceWorker.js into <Serviceworker/> component, and rendered in App.js.

Showing in browser UI instead of console does makes it very clear. Default "Offline Ready: message can also have unregister button and other messages with link explaining how to change. It can be very much be in your face.
Maybe we can have a default message in development mode also.

Should I make a PR with UI messages?

edit - basically it what @addyosmani suggested in his toasts comment. Looks really clear - no magic - render component to get default functionality with some UI to remind you

@bunshar - @viankakrisna has created PR #2426 for creating a toast.

Maybe take a look at his PR and do a review/leave some comments form your findings. I believe he did it a slightly different way.

commented

@jantimon Thanks for sharing your thoughts, this is appreciated. I think there’s a middle ground here but we need to explore it a bit further to find it.

I use "production" builds during development - much of my ui depends on a complex back end. There have been some references to triggering service workers based on "production" or "development" and I would like to make sure the solution for SW's allows them to be disabled for production.

@talkingtab you may completely disable service workers by removing the "registerServiceWorker" line in index.js.

Thoughts on PWA / Service Workers

TLDR: Agree with @jantimon. Too many issues. Not enough advantages for majority of users. CRA should 'just work'. Make PWA/SW optional.

Why was CRA created?
(Please correct me if I am wrong @gaearon)
image

CRA was developed due to the outcry of people who struggled to get started with React. There was boilerplate, webpack setup, babel transformations, and totally new paradigm in React.

It was provide an easy-to-get started application with sensible defaults that just work.

Problems with Service Workers
I consider myself a pretty experienced developer, and have created production ready offline-first webapps using AppCache/Manifest.

I have run into numerous problems since CRA introduced PWA by default. From localhost showing the wrong pages, to production-ready deploys breaking due to cache configuration, to issues with how chrome handles no-cache options.

And of course, others have encountered issues as can be seen from this thread. People who are confident enough developers to post on the github issues of the project.

Beyond that, Service Workers are new and still experimental. The spec is changing and browsers are playing catch up, with different behaviours. (Obviously this alone isnt enough. We need make a choice, thus why we use babel but also don't use stage-2 and stage-3)

Why were service workers added?
Offline capability and faster loading especially for mobile browsers seems to be a big win. And it totally is for some apps, it can be a huge benefit.

For most apps, its an 'added bonus', especially if comes free and doesn't impact on what people are doing.

Now the faster loading, that's hard to judge, because 'it depends'. With my own projects, I have cache-control setup the way we need and the the difference in negligible. (Bar the difference that PWA is forever-cached then updated, while cache-control requires a full reload after it expires). For projects with no-cache or very short caches, and large file sizes, the are probably substantial speed benefits.

Offline-first is great and now that older AppCache method is being removed from browsers this may be the only way to do it. However, it does require you to think about your app different. ]

Disadvantage of service workers
Many developer won't see much positive difference, but can encounter unexpected and unknown issues.

Some examples:

  • non-CRA Apps hosted on the same location:port as a CRA, currently break and will never be shown without manually deleting the service worker (e.g. localhost:5000 for CRA, and the for a static page). (PR #2438 tries to address this)
  • service-worker.js can be cached by the server and therefore doesn't get updated as expected when the rest of the site does. Another thing for developers to remember to do, no-cache on service workers. (This should get fixed when browsers implement the latest spec. Current only Firefox 53+)
  • Weird loading behaviour, where a user sees the old page and has to refresh to see the updated page. In a production environment, imagine having sale start at midnight. You update the site at midnight, users start to arrive and they see the old site with no sale. (PR #2426 tries to address this by giving a notification the user should reload the page)
  • Browser support. Users now experience different behaviour in different browsers depending if they support PWA/Service Workers and what version of the spec. Web Developers have always had cross browser issues, but we have spent a decade aligning them with pre-fixers, babel, build tools, etc. Now we are adding back different App behaviour between browsers.
  • Weird offline behaviour if you didn't design the app for offline use. Someone will use the app, it appears to work because of cached index.html/js bundle/css bundle. But then there is no data, images, and other things are broken. So you have a half working app which people aren't used to vs the normal 'offline experience' then comes up on websites.

Conclusion
None of these disadvantages are so great as to say 'No one should use PWA'. In fact, people should be using it, either for experiment, because you know what you are doing, or because its a big benefit for the type of app you are making.

But should it come as standard and default in create-react-app, whose point is to make it easy to develop in React without having to worry about all these setup issues?

CRA has been taken over a bit by developer like myself, who got tired of maintaining our own setup and thought using CRA would be easier, faster, give a better dev experience, give free updates (yay webpack2!) and let us focus on creating our apps.

But this means suddenly a lot of influence comes from experience developers.

I help teach beginner JS developers at a Bootcamp and meetups. I recommend they use CRA because it's suppose to 'just work'. I feel that Service Workers has partial broken the idea that it just works.

I don't believe that means it should be removed completely but maybe make it opt in by using the current config and an letting the user add registerServiceWorker().

/my 2cents. Personally, I am going to remove PWA 'on by default' from the react-scripts fork I maintain for our teams projects + my personal projects.

Wondering about the status on this?

CRA is a "no configuration"(NC) tool. CRA has earned a huge following because users trust that it is exactly that. This comment: 'you may completely disable service workers by removing the "registerServiceWorker" line in index.js' is not part of a "no configuration" system.

There are several options to fix this, but, as several others have said, I would prefer to keep services workers. A way to solve this and future similar issues is to add to the a "npm build experimental" command. I think this fits the CRA paradigm.

commented

We’ll leave this open for a while to let more people express their feedback.

I agree that Google’s own products having issues (Chrome, Firebase) is an indicator that this is not ready to be the default. I want to hear from more people about this, and especially for someone to compile a list of problems that need to be fixed for it to become a good default.

I think it’s likely we’ll change from default to easy opt-in in future versions because of feedback in this thread. But if we do, we need a clearly described list of issues which, when fixed (whether by Chrome, Firebase, etc), are enough to turn it back on.

Please keep the constructive feedback coming!

Other frameworks, like Ember, have solved this very problem allowing the development of addons. For instance, ember init creates a core project that works out-of-the-box while allowing the users to add more capabilities (like validation, offline support, authentication) by installing addons.
I think this project will benefit from that experience.
IMO, Service Workers should be an option and not part of the default scaffolded project.

@eabait it I don't think that makes sense for CRA. It makes sense for Ember which is a more curated framework from the get-go, while React is a much more community-grown affair and needs something that provides a sensible default.

React/webpack etc is very pluggable, you just have to eject. Creating a meta-plugin system that can operate pre-eject seems like a huge can of worms to me, and also misunderstanding the main offering of CRA.

CRA is not a scaffolding system like Yeoman. What CRA provides is a firm, predictable default that offers a shared reality. "I'm using create-react-app version 1.2.3" provides a lot of information that allows others to help you and also makes any kind of tutorial more predictable. If you start adding a plugin structure to it, you start adding different versions of reality and you're torpedoing the biggest selling point of CRA.

commented

Well put @mpj, this is pretty much how I think about it.

@mpj thanks for the clarification. Then, I think SW should not be part of CRA.

I'm all in for service workers. I upgraded immediately some of my cra projects to 1 to get the SW support. But cra is currently the entry point to react and in some cases to web dev for some. And I can totally can see how newbies can get confused. So I think we should make the simplicity the priority and make sws opt-in.

How about a "higher order package" create-reaect-pwa which would install CRA as dependency, forward all cli commands to it and simply inject the line needed for SWs when CRA is done?

I really appreciate @gaearon's openness to hearing community feedback about the pros and cons of keeping Service Worker support a default. It's been valuable hearing what Chrome and other browser vendors can do to improve our debuggability for PWAs. Ultimately, I'm supportive of whatever decision is made to ensure CRA continues to provide a predictable developer experience for users.

As the community shifts to offering better SW tooling across frameworks (we're working with Preact, Vue, Angular etc on this effort) we're aggregating specific work items we can tackle in both Chrome's SW implementation itself and Chrome DevTools. If we could come up with a set of browser items that we can work towards addressing here that would be appreciated. That way if/when SW are made an opt-in feature we can keep working together on improving DX to the point where they are less confusing.

@gaearon could you help @jeffposnick and I distill this list as you see it and we'll work on prioritization from our end?

Expanding on some of the comments from users:

What I like about Service Workers is they enable React apps to have resilience to transient network failures. If you're targeting mobile (a sizable number of Progressive Web Apps are built with React these days, including Twitter) this enables you to be able to use your app on the go and still deliver your users something meaningful when they hit a spotty network connection on a bus, in a coffee shop or while traveling. It's a nice to have if you're targeting users beyond desktop.

In Chrome, if you have a Service Worker registered and have cached scripts (like your React vendor bundle and your application code), we'll also early opt you into V8's code caching which can have a significant impact on the amount of React library code we need to parse and compile. Effectively, we can skip compiling from scratch and execute React app code much sooner. This means users can interact with your UI sooner than they otherwise would have if you were strictly relying on HTTP caching.

Are these things CRA should care about offering by default? Perhaps, but I'll defer to the project as y'all know what is most useful to users. I'd love to do what we can (fix bugs, more UX explorations etc) to make the overall PWA experience as stellar as we can even if that takes a while.

commented

I’m a bit overwhelmed by some other work right now so I can’t compose a good reply—but I think @ro-savage did a great job at outlining the issues, and it would be great if you could collaborate with him on creating a followup issue list. I’m happy to review and provide feedback on it, but I won’t find the time to write it myself in the coming days.

service worker for PWA!

commented

The fact that CRA has built-in service workers support was an important point why I choose CRA for scaffolding (even that I hate webpack).

But like most folks starting with PWA development I have struggled with some gotchas (my testing server was adding cache control headers to service worker file - debug that ;) ) before I understood how things are and I can understand frustration with new technology.

I believe optimal solution is to show some user notification as suggested #2398 (comment) by default that could be switched off by a config option.

Similar to projects like https://www.npmjs.com/package/create-react-app-sass we could also have a create-react-pwapp to let people pick SW explicitly.

I think that @mpj highlighted in his comment above the issues with adding a plugin structure to CRA

I see two issues:

  1. Dealing with SW now
  2. What to do in the future to avoid this

Issue 2 is more complex because of the (mostly) ambiguous comments about SW, which could be summarized as: "I'm glad SW is there but it caused problems".

Rewinding to the point of deciding whether to include SW (with our knowledge now) I would argue that neither "yes" nor "no" would have been the correct answer. Including SW added value to CRA for me, it was in fact a teaching moment, but one I wish I could have chosen. So +1. But the time and energy required on all sides has been excessive.

Proposal: there should be some mechanism that allows features like SW to be added to CRA. Such a thing should NOT violate the "No Configuration" dictum but I suspect there are ways to do this. I am thinking ENV=EXPERIMENTAL_ALL npm run build and ENV=EXPERIMENTAL_SW kind of thing.

  • It requires an affirmative action by the user to enable it
  • The word "EXPERIMENTAL" acts as a warning
  • It does not violate "No Configuration", CRA works out of the box.
  • It adds value to CRA and users by introducing new technologies

This is just a straw man (straw dog?) proposal, there are probably better ones.

Again, thanks to all for the constructive conversation and for CRA.

PWA should be forced as standard and service workers as part of it should be default in CRA. I think that now after service workers are default in CRA a lot of developers got in touch with it or hear about it for the first time and just that (educating more people) should be enough to leave it as default. As developer you should have nerves to handle frustrating problems and service workers can be frustrating no mater if you have experience with them or not. If you as developer have days that are not frustrating you should ask yourself if you are working hard enough 😉

Yes there are issues with it but with more and more people on the same boat we will fix them together faster and I'm sure that more issues can be found if more developers use service workers. It would also make pressure on Chrome and Firebase devs to fix their problems with it.

I'm using Firebase and it still has some problems with service-workers but the pros are way more than cons. My suggestion would be to add a comment above the service worker registration that describes a little what the registration line does and that you can comment it away if you don't want to use service workers.

I think that there are much more people that like service workers to be default but the other part having problems makes just more noise 😉 so let us scream "leave it as default" 😃

There are many ways to implement service workers, and several different scenarios in which they can be applicable. This is why I don't think they should be enabled by default, but rather an option. There are some great tools already available, and can easily be added to your project.

Considerations

  • Service worker caching should be considered a progressive enhancement. If you follow the model of
    conditionally registering a service worker only if it's supported (determined by
    if('serviceWorker' in navigator)), you'll get offline support on browsers with service workers and
    on browsers that don't support service workers, the offline-specific code will never be called.
    There's no overhead/breakage for older browsers if you add sw-precache to your build.

  • All resources that are precached will be fetched by a service worker running in a separate
    thread as soon as the service worker is installed. You should be judicious in what you list in the
    dynamicUrlToDependencies and staticFileGlobs options, since listing files that are non-essential
    (large images that are not shown on every page, for instance) will result in browsers downloading
    more data than is strictly necessary.

  • Precaching doesn't make sense for all types of resources (see the previous
    point). Other caching strategies, like those outlined in the Offline Cookbook, can be used in
    conjunction with sw-precache to provide the best experience for your users. If
    you do implement additional caching logic, put the code in a separate JavaScript
    file and include it using the importScripts() method.

  • sw-precache uses a cache-first strategy, which results in a copy of
    any cached content being returned without consulting the network. A useful
    pattern to adopt with this strategy is to display a toast/alert to your users
    when there's new content available, and give them an opportunity to reload the
    page to pick up that new content (which the service worker will have added to
    the cache, and will be available at the next page load). The sample service-worker-registration.js file illustrates the service worker lifecycle event you can listen for to trigger this message.

  • It's very important that the requests sw-precache makes to populate your cache
    result in the most up-to-date version of a resource at a given URL. Requests
    that are fulfilled with out-of-date responses (like those found in your
    browser's HTTP cache) can end up being read from the service worker's cache
    indefinitely. Jake Archibald's blog post provides more context about this problem.

Resources

Here are a few the projects I'm watching:

Workbox

commented

@addyosmani

Here is what I think is an emblematic example of Chrome usability issues.

I am running a file server on the same port as a React app which I last touched two weeks ago. React app pops up.

I Shift+Cmd+R for it to go away. It does. Then I click on another link on the same host and port, and bam—it's back again! I Shift+Cmd+R again. It goes away.

I click another link. Shift+Cmd+R yet again 😥 .

The last screen is especially funny (I have a bunch of iframes I need to test, and none of them show the right thing).

As a consumer I expect Shift+Cmd+R to wipe out the cache completely and delete the service worker. This combination is my last resort when things are broken. Since service worker "takes over" the whole website then I expect Shift+Cmd+R to be more aggressive in this case.

In my opinion tucking it anywhere into DevTools is a non-solution. It's not accessible to the end user, and even as a developer, I won't bother either toggling incognito or diving into DevTools when all I want is to view the website I'm interacting with now (rather than the one that was cached weeks ago).

Regarding #2398 (comment), I've restarted a discussion on the Service Worker Specification issue tracker about formalizing a procedure for unregistering the old service worker in the scenario you describe: w3c/ServiceWorker#204 (comment)

Specs take time to change, and even if they're updated, it takes time for browsers to match those changes. In the meantime, the modification to @ro-savage's PR I describe in #2438 (comment) would allow c-r-a to work around the scenario you describe immediately.

As to the behavior of Shift+CMD+R, the current behavior you're seeing—temporarily disabling the service worker, but not unregistering it—matches what's described in the service worker specification. Changing that temporary bypass into a permanent unregistration would have to go through the spec process as well, but perhaps it wouldn't be seen as necessary if they other changes are implemented.

My two cents: having this as default in create react app is causing issues we did a DNS cutover to another site. Users who ended up with service-worker.js are now "stuck" on the old site because the worker is attempting to hit the new DNS at /service-worker.js and the file doesn't exist, so it continues to show the old site.

Hitting Control-F5 brings up the new site, but hitting F5 brings up the old site again.

I just don't get why someone would want this behaviour - caching an entire site in the browser storage and continuing to show the cache if the currently site does not have service-worker.js

I could be completely misunderstanding how this works.

commented

@eric-tucker If this is a problem right now you can explicitly unregister it, as documented:

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 with a call to serviceWorkerRegistration.unregister(). After the user visits a page that has serviceWorkerRegistration.unregister(), the service worker will be uninstalled.

@gaearon That's not clear. I don't have src/index.js

Let's pretend the new site is absolutely no react (it's Drupal).

How does one solve this?

@eric-tucker I think you might want to paste this in your js:

  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.unregister();
    });
  }

Your trapped users will still need to hard refresh, but at least not-trapped users will have their serviceWorker removed.

Some want this behavior because they prefer a fast second load over a fresh second load. E.g. think of a page you might visit 100 times a day but only changes once every few days like the front page of facebook or google.

Personally, I'm on this github issue because I've been burned just like the gif @gaearon shared. My api is at example.com/api/bla and the react app was hosted at example.com/ which caused download links to the api to show index.html instead of the expected content.

If serviceWorkers stay I would request a route white-list and black-list to be included in registerServiceWorker.js so this behavior can be configured. I think the fetch event handler supports configuring the routes.

@ubershmekel users are stuck on the old version of the app with only requests to service-worker.js happening. Let's ignore the fact that default behaviour of the service worker created by create react app is caching index.html, there's only a single place I can attempt to hook into the running service worker to get it to stop, and that's in the code that refreshes itself.

So, with that in mind, is there any way to break the service worker from within its own code in service-worker.js (requests for this are being made at our Drupal site).

@eric-tucker, please see https://stackoverflow.com/a/38980776/385997 for an example of a service-worker.js that you can deploy which will effectively act as a no-op.

Sorry for the slow response. I've been MIA.

I've now created a consolidated issues list #2554

Until most of these issues are addressed, I highly recommend cutting a release without service workers and releasing that ASAP.

To reiterate what's been said.

CRA should be easy and just work. Service workers are not easy and do not just work.

Let a react offline boilerplate handle service workers and figure it out the issues first.

CRA should have it optional and off by default or remove it completely.

@gaearon - if you let us know what you'd like to do, I am sure @jeffposnick or I could do a PR to remove or make it optional. If it's removed, we could always keep it on a seperate branch including the fixes until it's ready for prime time.

Thanks for creating that consolidated list of issues. That's helpful. Perhaps we should PR making SW an opt-in until we've worked through more of the items in that list.

Perhaps my only feedback on the consolidated issue is it could be useful to categorize the items there. E.g UX/DX/browser.

Deferring to @gaearon for insight on preferred next steps.

Having Service Workers and PWA implemented in next would put it in the hands of thousands of react developers who are using a more 'advanced' framework that already had a lot of features and people don't expect to 'just work' like CRA.

@addyosmani & @jeffposnick maybe you could chat with @arunoda about adding it in by default, if you'd like to get feedback from developers. I can see they already use service workers for pre-fetching and have examples on setting up a next app as a PWA.

based on this http://www.phpied.com/create-react-app-sw-precache-pwa/ sw-precache can be added on the user space without the need of fiddling with webpack config. And I remember a long time ago I have made PWA compatible CRA generated project with adding a post-build command. I can't remember whether it's sw-precache or sw-toolbox.

It's sw-precache! after digging in my old private repo commits I'm doing the exact same thing the tutorial did. The issue at that time is the same one that we have right now (caching, updating the service-worker.js). If I had known that I need to serve service-worker.js with no-cache header maybe the build script still in the repo right now. :)

So I'm voting for removing the webpack plugin, but just add a tutorial about sw-precache in CRA docs.

index.js has the line serviceWorkerRegistration(), not serviceWorkerRegistration.register().

To unregister
change
serviceWorkerRegistration()
to
unregister()
and change
import registerServiceWorker from './registerServiceWorker'
to
import { unregister } from './registerServiceWorker' in index.js

I haven't read this whole thread so maybe this was covered already, but I found a case where service workers lead to confusing results.

My public/ folder contains two HTML files. One is the default index.html, another is a small thanks.html, which I want to serve directly. It's a small page that doesn't need React or any of the other machinery provided by CRA.

This works great at first. I can go to <my-page>/thanks.html and see the file.

But after I load the main page, said URL no longer works. It loads the main page instead. (without changing the URL).

The simplest way to fix this was to opt out of service workers. That's a shame though, because they're great at everything else. It sounds almost like the caching CRA's default service worker performs doesn't account for some filetypes in public/, and I don't know where to go to fix that.

Hello @Swizec—The service worker that's generated as part of the c-r-a build process will use the index.html "fallback" for navigation requests if there isn't a match for a given URL in the precache list.

The easiest way to resolve the issue you describe is to ensure that your thanks.html file is picked up in the list of resources that the service worker precaches.

I'm... actually not entirely sure what the best way to do that would be. The sw-precache-webpack-plugin should precache anything that's in the assets list that Webpack generates as part of its build (excluding files that match staticFileGlobsIgnorePatterns), so I think you'd want to figure out why your thanks.html file isn't part of the Webpack assets?

(CC: @goldhand)

commented

It's expected that it's not part of Webpack asset list because we manually copy any extra files in public into the build folder before running Webpack (or maybe after). Please file a bug about this. I'm not sure what the right fix would be. We intentionally don't let Webpack know about those assets because there may be thousands of them.

commented

@Swizec We can include assets that are not a part of the webpack asset list by adding two parameters to the SWPrecacheWebpack config:
mergeStaticsConfig=true and staticFileGlobs=['public/*']
This only works if the assets are copied to public/ before the webpack compilation process.

Respectfully, it seems that the rationale for not including redux, react-router, {insert-dependency-here} within CRA should also apply to service workers. Both are very opinionated choices and aren't really core to the mission of creating react applications quickly.

Having said that, I'm certainly not opposed to enhancing this project to including more robust functionality like redux support, generators, etc. But if that isn't the goal then I think service workers shouldn't be here as well.

2 cents.

Disclaimer: I have no idea how CRA works.

I'm not sure if this is again CRA ideology, but maybe it makes sense to have plugins/hooks which will allow usage of such things as serviceworker/redux/etc? I know the ideology is against any configs, but reading this issue gives an impression that it's possible to specify configs for some webpack plugins.

Wanted to pitch in and say, this needs higher visibility and some kind of informational text in install/readme.

I just spent quite some time debugging an app that cannot be cached for offline use which uses express session auth. While express was redirecting all requests to /login, only fetch requests to dynamic endpoints would get redirected and even after forcefully calling window.location.replace once a fetch was redirected, service worker would still cache the page load and keep the browser from getting redirected to login.

As @gaearon mentioned, this is a very powerful feature and I understand there could be need for it (offline use and aggressive caching) but this debugging experience left a very bad impression of service workers and CRA on me.

I'm having the same problem as sunsetfantastic in this reddit post. I didn't comment out the 'registerServiceWorker' code before running my app a few times and now I can't get ports 3000, 3001, or 3002 open. I've tried many suggestions including killing the process that was using the port from the terminal, unregistering service workers from Google DevTools, these steps, etc.

I've been trying to fix this issue on and off for about a week now with the help of multiple other people to no avail. Like sunsetfantastic I'm about ready to just reset my laptop.

I apologize if the actual fix is already in this thread but I couldn't find it. I read over half of the comments, but I did not read every single one because it's quite a long thread. Can someone please point me to a solution for opening up these ports and getting react off of them? I would hate to have to do something more drastic to clear this up :(

@meghanprestemon - You need to remove serviceWorkerRegistration.register() and add serviceWorkerRegistration.unregister() to your CRA app.

Once its unregistered on all your ports, you can remove serviceWorkerRegistration.unregister() as well

However, if your site is live on the internet, you'll need to publish it with the unregister and leave it there.

Alternatively, if you use chrome you can delete the service worker. Open dev tools, select Application choose Service Workers, check Show all. Then hit unregister on all the localhost urls.

Is it just me or did Facebook itself just run into this problem??? My Faceboook home page was coming back server error unless I hard refreshed, so I had to unregister the service worker and now it works fine again. Food for thought haha

This issue has been open since May . I was wondering if there was any status update on how and when this will be resolved?

I very much like the addition of ServiceWorker. I think it is an opinionated choice about the web as a platform and the api's we should support. However, I do not see it as a developer framework choice, such as redux, relay, apollo, etc. Just like React has to target certain browser versions, defaulting to have offline support with service workers is a good, forward looking decision that hopefully will push the web forward. I also love that it is the default, but is super easy to remove - just delete 1 line in the index.js file!

@ro-savage Thank you for getting back to me. As noted above, I have deleted ALL service workers through Chrome Dev Tools and that did not work.

Also, can you point me to where the serviceWorkerRegistration.register() method is? I have the following two lines of code in the index.js:

import registerServiceWorker from './registerServiceWorker';
.
.
.
registerServiceWorker();

which I have changed to

import { unregister } from './registerServiceWorker';
.
.
.
unregister();

and that doesn't work. I don't specifically see the method serviceWorkerRegistration.register() referenced anywhere in the index.js though. Should I be looking somewhere else?

I just wanted to check in again and see if there are any new solutions for this problem. I am still unable to get those ports free. Thank you

commented

@meghanprestemon Very sorry you're having issues. I pinged @jeffposnick and hopefully he can help you out.

commented

@meghanprestemon It would help if you could share your project, or at least the full content of your src/index.js and src/registerServiceWorker.js.

Hello @meghanprestemon—apologies for the delayed response. (I'm currently traveling, with less access to GitHub than usual, but I'll check in again for your responses.)

First off, it would be great to know what version of c-r-a you're using. There are some mitigations that were meant to prevent the official development server from running into this issue introduced in #2276, which should have been included in the 1.0.6 (or maybe 1.0.7?) release. I'd like to understand whether you're running into this because you're on an older version of c-r-a, or whether the changes in that PR still leave you in a confusing state.

Second, while it shouldn't be necessary to manually delete anything with the latest codebase, I'm trying to understand how you could be in a situation in which explicitly deleting the service worker registrations in Chrome DevTools could have left a service worker active. Have you quit Chrome in between deleting the registrations and trying again? Can you post a screenshot of your Applications DevTools panel, with Service Workers selected and "Show all" checked? It should look empty if you've deleted everything, like:

screen shot 2017-08-27 at 5 01 08 pm

And finally, could you try opening a Chrome Incognito window and then visiting http://localhost:3000? There's guaranteed not to be any pre-existing service worker registrations in place when you open a Chrome Incognito window for the first time in a session, and if you somehow see content at http://localhost:3000 from an Incognito window, then it's due to a "phantom" web server instance running on your computer, and not due to a service worker.

You probably know that service worker won't work on any iOS device (20% - 25% of all your users) and this is not about to change soon (maybe never).

Just a small update. Webkit will support ServiceWorkers. It is in development.

Check isserviceworkerready for the latest news.

So I know I am not adding anything new to this thread, but wanted to comment that I recently moved our web app from a VS2017 template to separate back end (web API) and front end, using create-react-app. The first build to staging wroked great but the a second build seemed to not have gone through. My coworker told me it worked fine for him, so I hit shift+F5 (windows user here) and it refreshed and worked as expected. I suppose its a PWA thing, which i think my app has no use for but I am not against of. However, I recall from learning the basics of Webpack that you could create hashes on file names automatically, allowing the browser to use cached files but use newer when available. Can CRA use this feature and would this fix or mitigate the issue? In case it's not obvious, I understand very little of what I am talking about...

@alebrozzoSP Unfortunately that won't work for service works / PWA.

Webpack is still creating those hashes, but the service worker will load in whatever was last used/saved.

It won't do a check against the server before loading the site (thus why you get instant load, it parsing and rendering before it even attempts to talk to the server).

Once it finds the that the file has changed / new hash. It will then ask you if you'd like to reload the page.

Am usually a vanilla JS guy, so a total noob to React. I needed a service worker for a new project, so I'm so glad it's already there. Works as expected. Keep it.

Thank you so much @jantimon for opening this issue. You saved my afternoon. After hours of invalidating CloudFront cache, fiddling with S3 settings, clearing browser cache, testing in incognito and banging my head against the wall trying to understand why "curl https://my_url/callback.html" gives a completely different result than requesting the same URL in the browser with DevTools open + cache disabled, I finally stumbled upon #2398. I had never heard of ServiceWorkers before. Great solution for off-line apps, terrible idea to have it "on" by default.

Hello all, new user here and I just wanted to give you my point of view on this topic.

While getting started with CRA, I wish I hadn't needed to spend half a day researching why service-worker.js, manifest.json and asset-manifest.json were magically appearing in my build and why I needed them at all. Everything else going on in CRA was extremely straightforward and including this by default seems to go against that spirit.

After learning about PWAs and service workers, I decided that these features are not worth the additional complexity for most of my projects. I also generally prefer to start simple and add features as I need them and not the other way around.

So, not only did I have to spend my time learning about something which is largely useless to me at the beginning of my project but I also incurred some technical debt in the form of my new build script (shown below) and even more time will be lost explaining all of this to junior developers who will take over the project in the future. I now also have to worry if CRA is going to magically put other things in my build in the future.

For now, here is my solution to disabling all of these things:

  • Remove registerServiceWorker from index.js as mentioned earlier.
  • Remove registerServiceWorker.js from the project.
  • Change my build script to: "build": "react-scripts build && rimraf ./build/service-worker.js ./build/manifest.json ./build/asset-manifest.json".

I did not delete public/manifest.json from my project because I'm not sure if CRA uses that file in any other capacity. Everything works if I do delete it, so probably not. I will have to revisit this in the future as I learn more.

@waynebloss the only required step is to remove registerServiceWorker() from index.js.