'What is NODE_ENV and how to use it in Express?

This is my app that I'm currently running on production.

var app = express();
app.set('views',settings.c.WEB_PATH + '/public/templates');
app.set('view engine','ejs');
app.configure(function(){
    app.use(express.favicon());
    app.use(express.static(settings.c.WEB_PATH + '/public'));
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.methodOverride());
    app.use(express.session({
            cookie:{ domain:"."+settings.c.SITE_DOMAIN, maxAge:1440009999},
            secret:'hamster',
            store: r_store,
            }));
    app.use(useragent.express());
    app.use(flash());
    app.use(passport.initialize());
    app.use(passport.session());
});

Now I've learned about NODE_ENV and want to use it. How can I do this?



Solution 1:[1]

NODE_ENV is an environment variable made popular by the express web server framework. When a node application is run, it can check the value of the environment variable and do different things based on the value. NODE_ENV specifically is used (by convention) to state whether a particular environment is a production or a development environment. A common use-case is running additional debugging or logging code if running in a development environment.

Accessing NODE_ENV

You can use the following code to access the environment variable yourself so that you can perform your own checks and logic:

var environment = process.env.NODE_ENV

Assume production if you don't recognise the value:

var isDevelopment = environment === 'development'

if (isDevelopment) {
  setUpMoreVerboseLogging()
}

You can alternatively using express' app.get('env') function, but note that this is NOT RECOMMENDED as it defaults to "development", which may result in development code being accidentally run in a production environment - it's much safer if your app throws an error if this important value is not set (or if preferred, defaults to production logic as above).

Be aware that if you haven't explicitly set NODE_ENV for your environment, it will be undefined if you access it from process.env, there is no default.

Setting NODE_ENV

How to actually set the environment variable varies from operating system to operating system, and also depends on your user setup.

If you want to set the environment variable as a one-off, you can do so from the command line:

  • linux & mac: export NODE_ENV=production
  • windows: $env:NODE_ENV = 'production'

In the long term, you should persist this so that it isn't unset if you reboot - rather than list all the possible methods to do this, I'll let you search how to do that yourself!

Convention has dictated that there are two 'main' values you should use for NODE_ENV, either production or development, all lowercase. There's nothing to stop you from using other values, (test, for example, if you wish to use some different logic when running automated tests), but be aware that if you are using third-party modules, they may explicitly compare with 'production' or 'development' to determine what to do, so there may be side effects that aren't immediately obvious.

Finally, note that it's a really bad idea to try to set NODE_ENV from within a node application itself - if you do, it will only be applied to the process from which it was set, so things probably won't work like you'd expect them to. Don't do it - you'll regret it.

Solution 2:[2]

NODE_ENV is an environmental variable that stands for node environment in express server.

It's how we set and detect which environment we are in.

It's very common using production and development.

Set:

export NODE_ENV=production

Get:

You can get it using app.get('env')

Solution 3:[3]

I assume the original question included how does Express use this environment variable.

Express uses NODE_ENV to alter its own default behavior. For example, in development mode, the default error handler will send back a stacktrace to the browser. In production mode, the response is simply Internal Server Error, to avoid leaking implementation details to the world.

Solution 4:[4]

Typically, you'd use the NODE_ENV variable to take special actions when you develop, test and debug your code. For example to produce detailed logging and debug output which you don't want in production. Express itself behaves differently depending on whether NODE_ENV is set to production or not. You can see this if you put these lines in an Express app, and then make a HTTP GET request to /error:

app.get('/error', function(req, res) {
  if ('production' !== app.get('env')) {
    console.log("Forcing an error!");
  }
  throw new Error('TestError');
});

app.use(function (req, res, next) {
  res.status(501).send("Error!")
})

Note that the latter app.use() must be last, after all other method handlers!

If you set NODE_ENV to production before you start your server, and then send a GET /error request to it, you should not see the text Forcing an error! in the console, and the response should not contain a stack trace in the HTML body (which origins from Express). If, instead, you set NODE_ENV to something else before starting your server, the opposite should happen.

In Linux, set the environment variable NODE_ENV like this:

export NODE_ENV='value'

Solution 5:[5]

Disclaimer: This answer may annoy quite a few people, but it has to be spoken. No offense meant, please try to consider a point of view wider than a developer's point of view.

To business:

This is an environment variable first popularized by the express framework, and later "leaked" to be used in different packages and services.

Specifically in express - when the value is anything that is not production - the library enters a development mode that is more forgiving, more debuggable, logs more and consumes more memory.

More common quirks is libraries of view-rendering or middlewares of view-rendering skip cache on non-production modes, expecting the files to be modified by developer between refreshes.

This is one of the confusing points in ops for nodejs and express.

This is basically an anti-pattern, coupling a behavior with a name of an environment.

What's wrong with that?

  • What if I don't want my tests to run in a mode that is different from production?
  • What if I have few cloud environments with different names, all of which need to function like produciton?

The name of the variable pushes many ops people to a trap, where they fill in NODE_ENV the name of the environment, and are surprised when they get from the same distribution different behavior and performance from what they get in production.

The result is that as a consultant I see that most teams had to come with a 2nd variable like OVERRIDE_ENV, NODE_ENV_NAME, NODE_ACTUAL_ENV and many more nonsense of that sort, and keep fighting with the ops that intuitively associate a name like NODE_ENV with the name of the environment...

A better name would have been EXECUTION_MODE, but that's a littsy bitsy too late to change now, so we're stuck with that, and unfortunately, not only in express...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pang
Solution 2 MarredCheese
Solution 3
Solution 4 Rein
Solution 5