DEV Community

Mohammad Faisal
Mohammad Faisal

Posted on • Edited on • Originally published at mdfaisal.com

Multiple Environments in NodeJS Application

To read more articles like this, visit my blog

For the production-level applications, we need support for multiple environments. For example, you will need to use different databases for different environments. There are many uses, and this is just one of them.

Today we will see how we can manage multiple environments in a NodeJS application.

Traditional way

The most straightforward way to use environment variables is using our package.json file.
Let's create two commands just to demonstrate two environments.

"scripts": {
    "start-dev": "PORT=3000 ts-node-dev --respawn src/index.ts",
    "start-prod": "PORT=4000  ts-node-dev --respawn src/index.ts"
  }
Enter fullscreen mode Exit fullscreen mode

We have defined two commands. For development, we have set start-dev where the PORT variable should have a value of 3000. And for prod it will be 4000.

If we run our application

yarn start-dev
Enter fullscreen mode Exit fullscreen mode

You will get the following message.

Connected successfully on port 3000
Enter fullscreen mode Exit fullscreen mode

and running start-prod will give you

Connected successfully on port 4000
Enter fullscreen mode Exit fullscreen mode

So we've successfully made our application configurable.

Let's take it one step further

So what if we need another variable that will change in different environments? We can just append another variable inside that string.

"scripts": {
    "start-dev": "PORT=3000 SOMETHING_ELSE=dev ts-node-dev --respawn src/index.ts",
    "start-prod": "PORT=4000 SOMETHING_ELSE=dev ts-node-dev --respawn src/index.ts"
  }
Enter fullscreen mode Exit fullscreen mode

Here SOMETHING_ELSE will be accessible via process.env.SOMETHING_ELSE

But in real life, we have many environments that need to be changed. How do we manage that?

Let's create an environment file

TO manage many environment variables, we can use an environment file. Head over to your project and create a .env file and paste the following there.

PORT=3000
SOMETHING_ELSE=dev
Enter fullscreen mode Exit fullscreen mode

And remove the environments from the package.json commands.

"scripts": {
    "start-dev": "ts-node-dev --respawn src/index.ts",
    "start-prod": "ts-node-dev --respawn src/index.ts",
  },
Enter fullscreen mode Exit fullscreen mode

And let's run!

yarn start-dev
Enter fullscreen mode Exit fullscreen mode

This will give the following output.

Connected successfully on port 5000
Enter fullscreen mode Exit fullscreen mode

Now that's weird. Because we are supposed to see 3000 as the port, but it's giving us 5000.

The reason is although we have added the environment variables, NodeJS is not going to read them automatically.

Let's read our environment variables

We have a very popular package to do that for us. The name is dotenv

Let's install that first.

yarn add dotenv
Enter fullscreen mode Exit fullscreen mode

And import it inside our application like the following.

import "dotenv/config";
Enter fullscreen mode Exit fullscreen mode

or like this

import dotenv from "dotenv";
const configuration: any = dotenv.config().parsed;
Enter fullscreen mode Exit fullscreen mode

And that's enough. You don't need to do anything else to read the environment files. This package will make the variables available for our application via process.env

To test that, you can run.

yarn start-dev
Enter fullscreen mode Exit fullscreen mode

And you will see the application running on PORT 3000 again.

Multiple Environment

Let's make our application production ready now. Let's create two separate files for separate environments.

Create files according to environment like .env.development and .env.production

Now we need to load the files during the bootup. Windows environments sometimes face issues with loading the environments. To take care of that, let's install a package named cross-env

yarn add -D cross-env
Enter fullscreen mode Exit fullscreen mode

Then create separate scripts for those inside package.json

"dev": "cross-env NODE_ENV=development ts-node-dev --respawn src/index.ts",
"prod": "cross-env NODE_ENV=production ts-node-dev --respawn src/index.ts",
Enter fullscreen mode Exit fullscreen mode

Then modify the config file like this:

import dotenv from "dotenv";
dotenv.config({ path: __dirname + `/../../.env.${process.env.NODE_ENV}` }); // change according to your need

const config = {
  port: process.env.APPLICATION_PORT,
  dbUrl: process.env.DB_URL,
  dbPassword: process.env.DB_PASSWORD,
};

export default config;
Enter fullscreen mode Exit fullscreen mode

And we can now use the configuration everywhere in our application.

import Config from "./utils/Configuration";

console.log(Config.port);
Enter fullscreen mode Exit fullscreen mode

That's it! Now you can have as many environments as you like and handle them easily.

Final words

Don't forget to add the .env files to your .gitignore files. Otherwise, all your secrets will be exposed.

Open your .gitignore file and add the following

.env.development
.env.production
Enter fullscreen mode Exit fullscreen mode

That's it.

Reach me out on my LinkedIN

Read more articles on My Website

Github Repo

https://github.com/Mohammad-Faisal/nodejs-environment-handling

Top comments (0)