NODE_ENV production alternative name - node.js

I have an Express.js app for which the production environment name is foo. So I start my app like NODE_ENV=foo node app.js. In general this is a bad idea.
Now my app knows it is in production, but Express doesn't know. Regardless of whether this is a good idea or not in general, is there a way to tell Express that it's running in production?

I think you're misusing the NODE_ENV setting. If you would set the value to production, ie. you're running Node in production enviroment (that you happen to call foo), Express would read it automatically.
You can use app.set('env', 'production'); to set the mode if you really must use NODE_ENV for other purposes. Then you would need a way to tell your app if it is in production mode, eg.
if (process.env.NODE_ENV === 'foo') {
app.set('env', 'production');
}
or introduce another environment variable and use its value: app.set('env', process.env.REAL_NODE_ENV); and then run with NODE_ENV=foo REAL_NODE_ENV=production node app.js
I would still suggest to use another environment variable than NODE_ENV to tell your app it's running on foo.

Related

When is process.env set to NODE_ENV?

I had to add this code to my project that has Express as a back end and React as a front end in order to deploy to Heroku (along with some other adjustments like the heroku-postbuild field). I am new to Express/Node and read process.env is the Node environment, but what does it mean to just check if it exists/is set to true? I see people use it to set process.env.NODE_ENV to development or production but am not familiar with this usage.
if (process.env.NODE_ENV) {
app.use(express.static('client/build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
if condition is there to check if NODE_ENV has been set or not (e.g., "" will evaluate to false).
* inside app.get() is a wildcard that matches any route a user could type in a browser for this server (i.e., http://localhost/*).
So what it does is that if the NODE_ENV is set to something (not necessarily dev or production environment), then for any route (or any web page on the site) requested, you are going to send the client/build/index.html file back - basically render an index (main) page of the website.
This environment variable (i.e., NODE_ENV) is defined, well, as an environment variable in some computer (e.g., VM somewhere on the cloud like Heroku). On a cloud, it would probably have "production" set as a value. On your laptop, it may not have anything as you are just testing it out, playing with it, etc. But production environment is quite important because this is where users of your app can see and use your app.
According to Express.js docs, "Setting NODE_ENV to “production” makes Express cache view templates; cache CSS files generated from CSS extensions; and generate less verbose error messages." Ref: https://expressjs.com/en/advanced/best-practice-performance.html
My guess is that it sends this index.html file while on Heroku, and does something else (depending on defined routes) when it is not.
This link may also help: https://dev.to/flippedcoding/difference-between-development-stage-and-production-d0p
P.S. Natalie noted that Heroku sets Node.js applications to use NODE_ENV=production by default since 2015. Ref: https://devcenter.heroku.com/changelog-items/688

Env variables configuration for multiple Heroku remotes ie. testing, staging and production

I am using 3 different git remotes during my development namely testing, staging and production (on Heroku). I have implemented a .env file to handle environment variables but just want to clarify that the way I have set them up is correct.
I have implemented the following to fetch the NODE_ENV var and uses it accordingly to append the .env var strings on the page depending on the NODE_ENV var I set.
env = process.env.NODE_ENV;
envString = env;
SHEET_ID = process.env['SHEET_ID_' + envString];
In the documentation, they discuss default env vars but I am unsure if Heroku has its own NODE_ENV var or how it works exactly, I have been setting it myself in my local .env (then when pushing I change the server NODE_ENV var to testing, staging or production)
Is my following understanding correct?
The NODE_ENV var is located in my .env - is this also default env var served from the environment ie Heroku or am I correct in setting the var myself in the env file and mirroring it on the server?
When pushing to a remote, depending on which, is the correct way to switch the env var NODE_ENV var in my local .env to NODE_ENV=testing, NODE_ENV=staging or NODE_ENV=production? Then the set vars from for eg Heroku dashboard would be used instead of the local vars.
Is this the best way to use the same code base through each remote without having to update my local files?
Do environments like Heroku serve a NODE_ENV var by default? I console logged process.env but only found my local set vars.
I am trying to design things to be as maintainable and efficient as possible and when I eventually do share my code with others I would like it to be as easy to implement as possible.
Following the 12 factor app principles all configuration should happen in the environment variables.
For your app this means
the .env file is merely a helper to put configuration in to the local environment for the application to work
every app on heroku (in your case staging,testing,production) will have their own config set via the heroku config commands. They will end up in the local environment of your application dynos, together with whatever your addons put there (for example database credentials).

Check if API is running within Heroku?

How do I check within my Node / Express app if it is running within Heroku?
My understanding is that .env files don't work in Heroku. So this line will crash the app in Heroku. So, I want to prevent running this within a Heroku environment.
const dotenv = require('dotenv');
dotenv.config();
One way you can do it is to create an environment variable called IS_HEROKU. On Heroku that's done in the app's dashboard, in the Settings tab, under Config Variables. Add IS_HEROKU: true. You can also use the CLI:
heroku config:set IS_HEROKU=true
It's described here.
You will now have access to it with process.env.IS_HEROKU. The value is a string.
I feel is simpler to use environment variables this way compared to using dotenv. If it was my project I would specify all the environment variables this way.

What is the reason to use process.env.NODE_ENV and process.env.ENV variables in angular2?

I am starting to learn angular2 and I see that in examples they override process.env.NODE_ENV and process.env.ENV variables in configuration file. This code is from webpack.prod.js from this example
// webpack.prod.js
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
What is the reason for overriding process.env.NODE_ENV and process.env.ENV variables. Is there something in nodejs or in angular 2 that use this variables?
One of the simplest use case would be to define the dev mode or prod mode wen bootstraping the app :
if ( 'development' === ENV && HMR === true ) {
// activate hot module reload
let ngHmr = require( 'angular2-hmr' );
ngHmr.hotModuleReplacement( main , module );
} else {
enableProdMode(); // which run Angular2 app in production mode
}
So in general , we can use them in a lot of different scenarios where you want to pass a variable from server ( i.e command-line ) to your app.
This is not something that is only about angular2. When you want to expose env vars from server to client, generally the best practices is to map them with slightly different names and only expose those items that concern the client.
This is so one can not simply look at your API endpoint that exposes env vars and workout all your server env vars.
In this particular example, it also makes sense from the domain perspective. As eventhough process.env.ENV might have the same value as NODE_ENV it does not represent the node.js's environment but the ENV in which angular is running.
It effectively from then on is process.env.NG_ENV or process.env.ENV

How to make custom environment works like production environment in expressJs?

I am new to nodeJs+ExpressJs app setup. I would like to run app.js in a custom environment.
For an example:
NODE_ENV=production node app.js will run the app in production mode and the view templates will be cached. But there is an option, that we can run the app.js in any custom mode like NODE_ENV=custom_environment node app.js. If it is the case, how to catch the view templates ? or will it catch for all the environment mode ? In-terms of development mode, I don't think view templates are cached.
You can choose which settings are used for which environment using app.configure:
app.configure('custom_environment', function() {
app.enable('view cache'); // enable view cache for this environment
// perhaps load middleware specific for your custom environment:
app.use(...);
});

Resources