facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
228.73k stars 46.82k forks source link

Explore encouraging users to not ship DEV mode to production #8784

Closed addyosmani closed 7 years ago

addyosmani commented 7 years ago

Do you want to request a feature or report a bug? Feature

What is the current behavior? Developers meaning to do the right thing will often accidentally ship DEV mode to production rather than PROD mode. This can have a significant impact on performance. Although DEV->PROD is a one line change, it's something React could explore encouraging.

There's great nuance here and I know that there's balance to be struck between the overall DX value this brings vs UX. Another challenge is that the change itself is trivial to make. It's unclear whether the right solution here is better defaults or stronger advocacy. Folks like @sebmarkbage have been acknowledging that this is a known issue so perhaps there's room for discussion to help improve this.

He's also noted that a switch from no warnings to DEV may require some folks to fix whole codebases which is also suboptimal. There may be an in-between solution worth talking about here however.

What is the expected behavior?

React encourages users to ship PROD mode to production rather than DEV. I would be open to a solution that is either provided at the library layer (or somehow tackled during build/bundling time by Webpack) that tries to ameliorate this.

This thread had a number of suggestions ranging from localhost detection, to alerts to injecting 'dev mode' messages to the DOM if used in a production environment. Something like this:

Alternatively, @thelarkinn was proposing that we tried to standardize on ENV configs being required to better facilitate detection of messaging like this. It's unclear which of these would be the most realistic. There are likely other ideas React core might have around how to tackle the problem.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

All recent versions.

This thread from @jordwalke prompted this issue. I think he also makes a fair point regarding benchmarks, but I care about how we can help folks ship the prod experience y'all have worked on optimizing to end customers in all it's glory.

aweary commented 7 years ago

@jide yes, but it's more important to address this problem correctly than quickly. Also, it can be implemented in a single browser before considering standardization efforts (if necessary).

jakearchibald commented 7 years ago

@aweary

are you suggesting that each framework should provide their own warning?

Given that each framework provides their own dev mode (and that mode may be very different between frameworks), it seems entirely fair that the framework should implement the warning in a similarly unique way.

Browsers have gone to some lengths to avoid exposing devtools to the page. If we're making devtools the barrier to entry here, we're going to miss a lot of users that a DOM warning wouldn't miss. A DOM warning seems not only simpler, it has fewer platform dependencies, and will reach more devs. Simpler & more effective sounds like a win.

addyosmani commented 7 years ago

@gaearon On the Chrome DevTools side, we've been brainstorming a live "violations API" that web platform & framework authors could use to signal important warnings. These would be presented somewhere like the upcoming Audits panel refresh. It sounds similar to your ask and could be used to trigger a warning on DEV mode detection.

For this particular issue, you may be after something a little louder than what we were originally planning. A violations panel, similar to console log messages, requires you to know a panel is going to provide insight. Perhaps there's additional UX room for something that displays a very visible page overlay lower down the page which frameworks could standardize on messaging for. Looping in @paulirish and @s3ththompson for their thoughts after the holiday weekend.

Fwiw, my guess is this API won't be ready for another few months. When it is, it will only be available in Canary initially and then 6-7 weeks later it might make it's way to stable.

A DOM warning seems not only simpler, but more effective.

I'm in agreement with Jake on this one. Let's keep chatting about the DevTools solution, but I'd also like to figure out what React might be open to doing as a fallback in case the API doesn't end up fitting your needs or is further out timeline wise.

aweary commented 7 years ago

Given that each framework provides their own dev mode (and that mode may be very different between frameworks), it seems entirely fair that the framework should implement the warning in a similarly unique way.

@jakearchibald you realize that setting that standard means pages utilizing multiple frameworks (or libraries that followed in suite) could result in an arbitrary amount of non-deterministically rendered cryptic warnings being displayed to end users?

Browsers have gone to some lengths to avoid exposing devtools to the page.

And I'm sure the reason is at least partially because developer-specific messaging should not be exposed to end users.

A DOM warning seems not only simpler, but more effective.

Nobody is arguing against the simplicity or effectiveness of the solution. It would work, but at the expense of compromising the user experience. Speed isn't the only thing that can negatively affect users.

aweary commented 7 years ago

Fwiw, my guess is this API won't be ready for another few months. When it is, it will only be available in Canary initially and then 6-7 weeks later it might make it's way to stable.

@addyosmani if its a better solution, I don't see how that would be an issue. Any changes to React would be in a major release, which I think is TBD as far as release timing goes anyways.

The solution decided upon will potentially affect all future development. A matter of weeks vs months in that context is acceptable IMO.

surma commented 7 years ago

I understand that some developers feel invaded if a framework injects something into their DOM that they didn’t put there themselves. But I feel like a banner at the bottom the page that says “This site is in DevMode” would be a great solution to this that doesn’t have a big impact on the user’s experience. I’d like to understand why a lot of people think the opposite.

@aweary: If a “security-focused” site ever launches in DevMode, they shouldn’t be trusted until they fix the issue. “DevMode” could include all kinds of security-related shortcuts like disabled CORS checks or exposed template source code etc. If a site is security-focused, this must not happen.

(I realize that “DevMode” has a very specific meaning in React, but I am trying to assume a non-developer’s perspective here)

jakearchibald commented 7 years ago

@aweary

you realize that setting that standard means pages utilizing multiple frameworks could result in an arbitrary amount of non-deterministically rendered cryptic warnings being displayed to end users?

I absolutely realise that. A page with multiple frameworks in dev mode will be severely damaging the user experience for no good reason. It seems you'd rather it goes unnoticed and unfixed. I'd rather it's so bad for non-developers (visible messages targeted at developers) that the developer fixes it promptly, creating a much better user experience.

Speed isn't the only thing that can negatively affect users.

I don't see anyone claiming otherwise? I'm pretty sad about this kind of reaction 😞

aweary commented 7 years ago

It seems you'd rather it goes unnoticed and unfixed

@jakearchibald that's kind of a strange conclusion, I don't think I'd be spending my free time here talking with you if I didn't want this to be fixed? Just because I don't agree with your solution doesn't mean I'm resigned to leaving it unresolved. That's really unfair.

I'd rather it's so bad for non-developers (visible messages targeted at developers) that the developer fixes it promptly, creating a much better user experience.

That's what I think is fundamentally unacceptable: you're explicitly punishing users first.

If a “security-focused” site ever launches in DevMode, they shouldn’t be trusted until they fix the issue.

@surma dev mode is not inherently insecure, but regardless it's stepping over the line to assume it's OK for you to communicate that to users.

sebmarkbage commented 7 years ago

I don't think a solution that requires opening or enabling dev tools is sufficient. For this to get noticed it needs to be visible to QA, management and possibly end users. Developers will be too used to seeing this. Similar to how problematic ssl configurations are highlighted. It doesn't need to be much but enough to be noticable that someone will ask about it and then get it fixed.

Injecting into the DOM is problematic for many reasons. It's a bit more feasible for React since we're a DOM library and have DOM entry points. It's harder for libraries that are not DOM specific and might run in a worker.

One thing we might be able to do is change the favicon as long as we provide a way to override it explicitly. Many sites already have separate favicons for development mode.

We need to figure out a default experience for handling errors in React which may not be able to keep the DOM in place. The current default implementation in master deletes React content from the tree if an error is thrown. That is also invasive.

If we had a way to detect that you're not in development mode we could trigger that error mode. We really need a solid way to opt into a development mode permanently then.

aweary commented 7 years ago

Similar to how problematic ssl configurations are highlighted.

This is exactly the kind of thing I think would be perfect. Users are already used to browsers providing security information about sites they visit, performance information isn't a huge jump from there. Plus, it would be consistent for all frameworks/libraries that report potential performance issues and would not directly interfere with the user workflow. 👍

jide commented 7 years ago

I like the favicon idea : Noticeable, works without devtools or extension, noticeable by everyone, does not do harm to users, can be animated to draw attention, annoying enough to make devs want to disappear.

capture d ecran 2017-01-14 a 17 13 43 1

mattecapu commented 7 years ago

What about making DEV mode opt-in? We err on the "good UX" side, because bad DX is easier to notice (and IMHO for issues like this users should "win" because they can't choose, while devs can). I'm sure some frameworks already do this (like Relay if I recall correctly).

Proposals on how to implement it:

The first seems the best because the other two may be hard-coded without a guard (such as an if(NODE_ENV === 'development') statement) and thus be shipped to production anyway.

sebmarkbage commented 7 years ago

@mattecapu See my second comment regarding. https://twitter.com/sebmarkbage/status/820047144677584896

If there is a similar way to enforce that developers start out by running in DEV mode then it doesn't matter what the default is. But it is really bad if you fall behind.

aickin commented 7 years ago

There's a lot to comment on here, and I have thoughts, but I'd like to weigh in specifically on just the question of how to disable a dev warning.

I'm not a huge fan of a button that disables a DOM warning for a set amount of time in one particular browser. As @jlongster points out, it's a pain for devs if it happens frequently. But more importantly to me, it introduces browser-specific variability in behavior, which could easily lead to "but it works fine on my machine" irreproducibility of bugs.

I'd prefer a parameter sent to render that lists domains that are considered dev boxes, with a default value of ["localhost", "127.0.0.1"]. It would look something like this:

React.render(<App/>, 
  myDiv,
  () => { console.log('finished render!'), 
  { devDomains: ["localhost", "devbox.mycorp.com"] }
);

If the current domain is in the list, then the dev warning never shows up. Otherwise, it does. Under this regime:

The one thing that worries me about this solution is that it might lead developers to leave in a list of all their dev server domains in the code, and that code may make it to production. For companies that consider their dev server domains to be a secret, that'd be a problem. Thoughts?

aweary commented 7 years ago

@aickin the problem with that approach is that it requires users to be aware of the configuration and, in turn, the problem it's solving. The issue is that people aren't aware of the dev/prod distinction in the first place.

Edit: nevermind, I see, there's still a DOM warning in development.

gaearon commented 7 years ago

Server side environments fix this by showing a "special" error page that includes debug details and also tells you to not to serve it in production.

Since we plan to make React "fail fast" and unmount views unless you provide a custom error boundary, we might as well add a default "red box" error boundary in development that acts as an educational page.

Then, the first time the user has a bug in production, they will see a special verbose error message. This could be an opportunity to educate about the DEV build.

Pajn commented 7 years ago

But I feel like a banner at the bottom the page that says “This site is in DevMode” would be a great solution to this that doesn’t have a big impact on the user’s experience. I’d like to understand why a lot of people think the opposite.

Most users dislikes web apps if they know that it's a web app, why? Because a previously common mentality of the web was that when it shows up on the screen it's done, no matter how bad it behaved and users have learned that the web is bad. However it's perfectly possible to create a great UX on the web, but to do that I must own the DOM. If someone injects random banners at arbitrary places the wrong element may start to scroll, or it may cause the whole screen to repaint on scroll or it may interfere with for example drag gestures or something else. The point is, as long as that banner is up I can not develop because I can't know that the experience is the same when that banner is gone.

As a framework solution I really like the favicon idea, it does not hinder development, it does not look to strange for users, it does not possibly destroy the UX but it will get noticed. However, it really only works for a single library or framework at the time and it does not work at all for libraries that run in workers. The real solution is a good way to do this through the browser that can support multiple frameworks and libraries and can be accessed from all contexts.

Another solution that supports multiple frameworks and libs and is more clear, but does require a permission request, is to show a browser notification.

srhise commented 7 years ago

Here's an idea: update the getting started docs on react's homepage to push create react app more heavily. And stress the importance of npm build in those docs. We don't need a DOM warning, we need awareness.

scottohara commented 7 years ago

I think @ropilz touched on this earlier in the thread with his "..we could even bind any service we want to notify devs.." comment, but it may have gone unnoticed (or not acknowledged).

As I understand it, the fundamental problem being solved here is

What if there was something analogous to CSP's report-uri, for frameworks to send dev mode warnings to, rather than showing a warning in-situ on the site where they would be visible to end-users?

Obviously there are a number of things to be considered, such as:

  1. Such reporting would ideally be ON by default, but what would the default report-uri be? (would we expect each framework to host their own free service, similar to https://report-uri.io? (this may possible for large, company-sponsored frameworks like React & Angular; but certainly impractical for smaller open-source frameworks like Preact, Vue etc.)
  2. Once a warning has been reported, how is the site owner/developer notified? (perhaps a good way for non-devs to get involved with a project, by volunteering to monitor these reports and help track down/notify the maintainer?)

I fully admit this suggestion is only a thought-bubble, and I haven't considered how practical this would be or how it would actually work; but I wanted to raise it as it seems to me that the challenge of 'reporting on production issues' has already been partially solved for CSP/HPKP reporting, and perhaps we could explore something similar here?

KrisSiegel commented 7 years ago

It's important to take a step back and realize React is a framework. You must not:

It's not React's job to babysit developers. I propose either:

  1. Make development mode opt in. When the developers realize they can't debug something they'll look up how to turn it on (which needs to be documented everywhere). No, it's not React's job to tell them to turn it back off. Their problem.

  2. Leave it to a simple console.log message (and this must be disable-able). Let developers find it and handle it. If they don't, oh well. You can't reach into every organization and make them do things correctly. It's just not scalable.

pveyes commented 7 years ago

I have to disagree with touching the DOM to display a warning. It looks easy and simple for React because it's a DOM library, but imagine if all libraries have to display their own warning in the DOM. It will be a total mess.

There's so many libraries that developers use that probably have their own dev mode. I think setting process.env.NODE_ENV to production has already been a common standard in bundling modules for browser. This is what we need to improve the awareness of.

I do agree that React docs doesn't prominently show that there is difference between dev and production build. When you open the docs, you have to go through Advanced Guides to read the difference between dev and production build. The title is Optimizing Performance, something that beginners definitely won't take a look because they use React because they heard that it's fast. I think the docs could be improved to have another docs titled "Using React in Production" or similar in Quick Start section.

Beginners doesn't usually read Advanced Guides but they will open some links in Quick Start if the title is clear enough and looks important. I know I did because that's what I do when I start learning React. I didn't read the getting started guide, but I do read some pages in Quick Start section.

Another approach we could take is showing warning in console when React is used in dev mode with link to fix that point to the docs. Opening console in production for developers is unusual, but in local env when developing they will certainly open the console. This way when developing locally, they will aware that they need to do something before publishing to production.

jakearchibald commented 7 years ago

http://code.gov launched despite console warnings. This is exactly the kind of thing we should aim to prevent. (That site is Angular, but the same applies to React)

matthewp commented 7 years ago

Here's the issue for code.gov if anyone wants to reach out to them (or send a PR): https://github.com/presidential-innovation-fellows/code-gov-web/issues/221

pveyes commented 7 years ago
Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.

I've never used Angular 2 before (which makes me beginner in this case). My initial reaction after I see the warning is I just try calling enableProdMode(). It doesn't work. I think the console message for Angular case could be improved. Instead of relying on magic, they should point to the docs.

Opening the Angular docs, I don't see anything about production build. I think this is a problem for both Angular and React. They both use dev mode, but they don't tell people up front in the docs on how to disable it. That's why improving the docs could go a long way on educating developers

I'm not against showing user warning when developers make "mistakes", but injecting some random DOM element is just intrusive. I love how browsers handle HTTPS problem where the browser have dedicated UI to show that the site is insecure. We don't have one for performance related status. Given rising concerns about web performance in general, I don't see why browser vendor doesn't come up with ways to tell user that the site they're visiting sucks.

thabti commented 7 years ago

This should be addressed at the tooling level, so possibly webpack and Babel can notify the developers of the benefits of setting a NODE_ENV.

jakearchibald commented 7 years ago

@pveyes Agreed, I've made the same point to the Angular team.

@matthewp there's a much older issue about this https://github.com/presidential-innovation-fellows/code-gov-web/issues/129 and the Angular team have reached out directly and given them the fix - there seems to be little desire to apply it. Question is, would a DOM warning have made this fix more urgent, or have prevented it launching in dev mode to begin with?

KrisSiegel commented 7 years ago

Question is, would a DOM warning have made this fix more urgent, or have prevented it launching in dev mode to begin with?

More than likely they would see the warning in development, Google how to disable it, and disable it. Then deployed it in dev mode without realizing it in the future because they forget. During development you want it to look like production so you can't have some random chunk of DOM being inserted. You can't have a QA or staging system seeing this either as it wouldn't be indicative of production.

So you end up with a bunch of junk code disabling this thing that screws with the site's UX. It's not like the original engineer who disabled it during development would necessarily remember either; they may have even moved on before it went to production.

I'm not sure how the deployment process works at code.gov but if it's anything like what I experienced as a government contractor than an accidental development mode deployment into production would either:

  1. Force a full rollback of the entire deployment (some of which take 6 months to get approval for and bundle in everything from UI changes to server software updates), likely the next day, then you get meetings and follow-up paperwork regarding what happened and scheduling a new deployment window (you'll get asked, over and over again, if the DB scripts or services or whatever were all in dev mode because of a single warning in the UI). I've seen this happen for very minor things. Sometimes you can get exceptions but YMMV.

  2. It would get noticed by users, it would get corrected but since it's likely not impacting function would not get updated until the next deployment window. So all users get to see it for weeks or months.

At least that was my experience. Point being, even if a DOM intrusion is noticed immediately after deployment, you don't know what their infrastructure / process is like and it may not be something they can fix immediately (even though they should be able to).

keyz commented 7 years ago

Warning messages will be more noticeable when #7360 (yellow box) gets merged. We could also add a message to the yellow box (call it "React Development Mode Warnings"?).

screen shot 2017-01-15 at 20 43 33
gaearon commented 7 years ago

Opening the Angular docs, I don't see anything about production build. I think this is a problem for both Angular and React. They both use dev mode, but they don't tell people up front in the docs on how to disable it. That's why improving the docs could go a long way on educating developers

It is right on the Installation page:

https://facebook.github.io/react/docs/installation.html#development-and-production-versions

And on Optimizing Performance:

https://facebook.github.io/react/docs/optimizing-performance.html#use-the-production-build

I don't think it's fair to say docs are not upfront about it.

gaearon commented 7 years ago

When you open the docs, you have to go through Advanced Guides to read the difference between dev and production build. The title is Optimizing Performance, something that beginners definitely won't take a look because they use React because they heard that it's fast. I think the docs could be improved to have another docs titled "Using React in Production" or similar in Quick Start section.

It is right there, on the very first page (Installation):

https://facebook.github.io/react/docs/installation.html#development-and-production-versions

pveyes commented 7 years ago

You're right. Sorry, my bad. I assumed that production build is in different section so I didn't look there and search for relevant title in sidebar instead (and found the Optimizing Performance page). I should've known better.

pveyes commented 7 years ago

I'm not really a beginner to React, that's why when I open the docs to verify my assumption - that React docs is not upfront about prod vs dev - I didn't open Installation docs 🙇

gaearon commented 7 years ago

No worries. If it's not visible enough I'm open to suggestions for better placement. For example we could make a dedicated page for it (Deploying to Production).

sebmarkbage commented 7 years ago

Let's not forget that this issue is a important issue to solve but not the most important issue to highlight. I'm also not convinced it will be sufficient even if highlighted at the very front page because people will see it and browse through, forget about it, and think "I know what I'm doing". So I wouldn't over pivot on the docs thing.

The only real way to address it is by detecting and notifying.

@KrisSiegel The favicon getting cached is a good point. I wonder if we should just switch it after a second or two and then flip it back briefly every few seconds. That way the caching and bookmarking issue is very unlikely to time it at the time of the overridden icon.

gaearon commented 7 years ago

I thought JS manipulations to favicon don't get cached but maybe I'm wrong.

taion commented 7 years ago

I'd argue that the right place to have hooks for this is not Chrome or Firefox, but rather webpack, Browserify, or Rollup.

Building what's intended as a production bundle for React but without enable production mode is just that – a build error. I think the reason there isn't agreement over how to present this at run time is reflective of this not being a problem that should be handled at run time.

kennylavender commented 7 years ago

@taion I agree. I think this definitely belongs in the build tool, not in the DOM.

I think it should be the build tools place to make the assumption that node env should be set to production for production code. It may not be required for all projects, but I do think it is a good assumption.

If npm run build is ran in the terminal, and the env is not set to production, then you should get a red warning in the terminal along with the default output: env is not set to production, some scripts may be in development mode

Currently I get no such warning from webpack.

Edit: added clarification

taion commented 7 years ago

Or just set NODE_ENV for you, really.

jakearchibald commented 7 years ago

If console warnings aren't working, I'm not sure build warnings will.

taion commented 7 years ago

The build should either configure things for you, or else fail if misconfigured for production. At least for React, this is a build time flag.

kennylavender commented 7 years ago

@jakearchibald I am sure it will still be ignored by some, but at least the warning would be shown to them when they build it, instead of not being seen because the warning is hidden away in the browser console which they may never open in production. Most importantly it gives those with less experience a clue about what they should be doing to make the code production ready.

jide commented 7 years ago

While many devs will update libraries, it is common not to update webpack and more generally tooling, because a lot of people make the assumption that it just works, and it may be a pain to update webpack and co.

aickin commented 7 years ago

Building what's intended as a production bundle for React but without enable production mode is just that – a build error.

Using a prepackaged version of React from a CDN is also a supported configuration, but there's no build step at all in that workflow. Therefore, a solution to this issue that only focuses on the build would ignore the CDN use case.

I'm honestly not sure how I feel about that; I can see arguments both for and against having dev warnings for React CDN usage.

@taion As someone who supports a build-only solution, do you think this is an important use case to cover?

What do other folks think?

taion commented 7 years ago

I think the documentation there is pretty clear that you should use the .min.js bundles for production. Maybe it could use a bold, a bigger font size, something like that. But if someone is using the unminified React bundle in production for their website, they have other problems anyway.

aickin commented 7 years ago

I think the documentation there is pretty clear that you should use the .min.js bundles for production.

Agreed, but the page is also pretty clear on how to configure your build tool for production if you include React as an npm package. I think the whole point of this issue was to try to create a pit of success for folks who don't carefully read that page of documentation.

It sounds like you may disagree, though, and that you think that using the dev build from the CDN is not an important case to prevent with a more aggressive dev warning. Is that a fair summary of your position, or am I missing some nuances?

taion commented 7 years ago

I think the CDN+dev configuration is more obviously wrong, in that it requires the user to use a unminified build of React. It's harder to fail in this manner because the burden of knowledge required to just use the minified build is lower.

The configuration where you think things are production-ready because you've run minification in webpack or Browserify but actually you aren't because you didn't set NODE_ENV – you can't get that via the CDN bundles.

rohmanhm commented 7 years ago

I think React tab on Chrome Developer Tools enough to tells If we're in DEV Mode.

glenjamin commented 7 years ago

I think it's worth noting that there is some precedent for a framework injecting a DOM element into the page in dev mode:

http://symfony.com/blog/new-in-symfony-2-8-redesigned-web-debug-toolbar

Although as far as I can tell I don't think this is on by default.

Following the discussion above there seems to be a general aim to achieve a perfect solution which satisfies all the constraints but reliably stops everyone from running in dev mode when they shouldn't be. The OP stated that there would need to be a tradeoff between the potential experiences for developers and users, and I think this is very much the case.

To attempt to re-state the problem a tad:

Given these, I think a decent first step would be for React in dev mode to announce that it is in dev mode via a console.warn or console.info with instructions to make sure this is disabled for the production deployment.

Sure, this won't catch everyone but it's a decent start which should reduce the number of people inadvertently shipping to production and doesn't close off any doors for future improvements.

gaearon commented 7 years ago

Given these, I think a decent first step would be for React in dev mode to announce that it is in dev mode via a console.warn or console.info with instructions to make sure this is disabled for the production deployment.

It is not wrong for it to be in development mode though when you're... developing. What other heuristics could we use?

Also, given that nobody reads console on production, I wonder if we could throw inside a timeout so that it gets logged if you use crash reporting solutions.

glenjamin commented 7 years ago

It is not wrong for it to be in development mode though when you're... developing. What other heuristics could we use?

I think it should be similar to the current React DevTools notice

screen shot 2017-01-17 at 14 03 04

An informational message that reminds you you're in dev mode and that dev mode should be disabled for production sites. This (in theory) should make more developers aware that there is a distinction and some action needs to be taken to prepare for production use.

Like you say, almost no-one is going to see a console warning in actual production - and by that point it's a little bit late.