This has come up a couple times lately as being an issue (#6479, #6581, #6511), I think perhaps because we added the minification warning and people are ending up seeing they aren't getting prod code when they expected it. But there's also the argument that you want React to be production and still use NODE_ENV for other purposes.
There would be a few things to figure out to make sure envify works, and deciding what we do for other projects which currently also use the NODE_ENV pattern (eg, Relay, fbjs, third-party code, etc).
This might not be a good idea at all though and definitely isn't happening immediately, but wanted to start the discussion.
Seems like NODE_ENV
is a solid pattern for all libs to use in the bundled-front-end-generation of apps, but not REACT_ENV
.
Makes no sense for redux to use REACT_ENV
, it's used in other contexts, so then we get REDUX_ENV
too? RELAY_ENV
, REACT_ROUTER_ENV
, REDUX_ENV
, EVERY_DEPENDENCY_IN_MY_SYSTEM_ENV
:|
If you must not conflict with NODE_ENV
, maybe BUNDLE_ENV
or BUILD_ENV
and the world can follow suit.
Maybe REACT_ENV
can override NODE_ENV
but it would be optional?
I like the idea of people being able to set REACT_ENV
(or whatever else you want to call it) but fall back on NODE_ENV
by default. that way, like @ryanflorence pointed out, you do not have to have a special environment variable for _every_ library you are using by default, but if there is something tricky or fancy you are trying to do you could explicitly set an environment variable to override it
EVERY_DEPENDENCY_IN_MY_SYSTEM_ENV
Definitely want to avoid that.
If you must not conflict with
NODE_ENV
, maybeBUNDLE_ENV
orBUILD_ENV
and the world can follow suit.
Yea, this is interesting and could be an approach to take. There's also the concern that sometimes you are running in Node and do want NODE_ENV
so fallback might be necessary as others have proposed. That would make our transformed code even uglier (at least until we have more confidence minifiers can handle the output of https://github.com/facebook/fbjs/pull/86)
Thanks for the quick feedback all!
Babel is an interesting case because people use it both on the client and in production, and env
in .babelrc
reads from BABEL_ENV
with a fallback to NODE_ENV
(which is what most people specify). Introducing BUNDLE_ENV
could be a solution but I feel like it would make the Babel situation more confusing.
Historically, I run code in both "qa" and "staging" NODE_ENVs.
For minification to work and accurately reflect what will soon be on "production", the builds run with NODE_ENV as "production", but client-side code checks against STAGE for the true environment (as our loggers and reporters call differently based on the actually environment).
Point being, I think it's exceedingly difficult to solve this on the vendor side when the NODE_ENV pattern is so prevalent.
There's a point where the lookup will always be faked to meet the needs of the build.
I wonder if there's something more we can do in user land to resolve this?
NODE_ENV is a really well established standard across the entire JavaScript ecosystem. As I see it, there's nothing wrong with people having something like APP_ENV
for supporting people's own list of dev, qa, staging, prod etc. We need a consistent way to determine whether an app is running/being built in an optimised mode, or a development mode. NODE_ENV provides that brilliantly.
There may be cases where it is useful to put one specific library/part of your code into development mode, while everything else is in prod mode (or visa versa) but I think it's a corner case. This is not what's being asked for in any of the three linked issues. I think we should wait until someone actually wants the feature before we build it, and if we build it it should be as @stubailo (an optional variable to override the default NODE_ENV behaviour).
I think it's worth noting that it should be possible to write a browserify transform/webpack loader which applies a different environment variable to a specific library. This way it will be useful to all without needing each library implement a separate environment variable.
And babel-plugin for that matter (which would then work server side). I really like that suggestion.
It seems like NODE_ENV
variable is often abused in Node.js community. In React Starter Kit we recommend to use NODE_ENV
only to distinguish between "production" (optimized, aka "release") and "development" (non-optimized, aka "debug") builds. And use some other env
variable to differentiate between multiple deployment types e.g. process.env.DEPLOYMENT
= production | staging | qa | test
.
It sounds like people are (cautiously) positive to an optional, overriding env var. Since we are only toggling between a release/optimized/minified build and a debug/dev build, could we maybe have that reflected in the name & values of that var?
The pattern X_ENV = production | staging | test | etc
is used in many overlapping ways across different languages, ecosystems and projects. This seems to be the main source of confusion. I would avoid copying that pattern into REACT_ENV
, since it does not actually express what we're trying to do.
Our variable
With those requirements, I would suggest something along these lines:
REACT_RELEASE_BUILD = <any value> | <empty string>
or maybe
REACT_BUILD = release | debug
Using strings for a "boolean" value is problematic; you might expect "false"
or "0"
to be handled the same as ""
.
On the hand, using specific keywords easily devolves into bikeshedding ("release"
vs "optimized"
vs "production"
etc).
_Edit: accidentally posted early, revised text a bit._
I just feel like this ship has sailed. A ton of libraries in the React ecosystem already rely on NODE_ENV
for better or worse, and changing this will involve a ton of churn. What鈥檚 worse, if we change it but people don鈥檛 update their configs, their code will silently fail to dead-code eliminate in popular bundlers like Webpack.
Also, as I mention in https://github.com/facebook/react/issues/7512#issuecomment-334137262 regarding staging
environment:
React 16 ships with separate entry points for production CommonJS bundles in
react/cjs/react.production.min.js
andreact-dom/cjs/react-dom.production.min.js
. You can aliasreact
andreact-dom
to these bundles to force a production environment even ifNODE_ENV
says otherwise.
So there is a workaround.
Most helpful comment
Seems like
NODE_ENV
is a solid pattern for all libs to use in the bundled-front-end-generation of apps, but notREACT_ENV
.Makes no sense for redux to use
REACT_ENV
, it's used in other contexts, so then we getREDUX_ENV
too?RELAY_ENV
,REACT_ROUTER_ENV
,REDUX_ENV
,EVERY_DEPENDENCY_IN_MY_SYSTEM_ENV
:|If you must not conflict with
NODE_ENV
, maybeBUNDLE_ENV
orBUILD_ENV
and the world can follow suit.