How to Create Configurations for Different Environments in Your Node Applications
Tags: javascript, webdev, codenewbie, tutorial
Published: 2020-07-21 06:10:56

Having multiple configurations can be handy for your node applications. It is quite probable that your applications will run in different environments and require slightly different configurations between them. For example, when you are developing, you may be using your local mysql for your database connection; this will not be the case in a production or stage environment.

This article will show you how to set up different configurations, for different environments, across your applications.

## Contents
1. [Basic setup](#basic-setup)
2. [Creating your npm scripts](#npm-scripts)
3. [Configurations](#configurations)
4. [Implementation](#implementation)
5. [Conclusion](#conclusion)

-----

## Basic setup
What you need to do:
1. Create your package.json file using npm init.
2. Save the *[config](https://www.npmjs.com/package/config)* dependency in your application.
3. Create your index.js file, which will be your entry point specified in step 1.
4. Create your configuration files inside a *config* directory.

```bash
npm init    # accept defaults
npm install –save config
touch index.js

# create configuration dir and files
mkdir config
touch config/default.json
touch config/production.json
```

-----

## Npm scripts
Now, create 2 scripts, which:
1. set your NODE_ENV to test and runs your application
2. set your NODE_ENV to production and runs your application


**The NODE_ENV should be set to the same name as one of your configuration files.** If it is not, then the default configuration will be used.

In this example, you set your NODE_ENV to *test* and *production*. As *test* does not have its own configuration file, the default will be used. Production does have its own configuration file, therefore your production configuration will be used, when running production script.

**Linux**
```javascript
“scripts”: {
  “test”: “export NODE_ENV=test && node index.js”
  “production”: “export NODE_ENV=production && node index.js”
}
```

**Windows**
*Notice the lack of a space before the ampersands.*
```javascript
“scripts”: {
  “test”: “set NODE_ENV=test&& node index.js”
  “production”: “set NODE_ENV=production&& node index.js”
}
```

-----

## Configurations
Now, add your configurations:
1. Default configurations
2. Configurations to be used in production


The default configurations will be used across all environments. When a property cannot be found in its specific configuration mode, then it will check to see if it exists in the default configuration before throwing an error.

**config/default.json**
```javascript
{
  “database”: {
    “host”: “localhost”,
    “port”: 3306,
    “username”: “root”,
    “password”: “Passw0rd!”,
    “dbName”: “app”
  }
}
```

**config/production.json**
```javascript
{
  “database”: {
    “host”: “192.168.1.1”,
    “username”: “root”,
    “password”: “somethi1ngAbitM0r3Secur3”,
    “dbName”: “app”
  }
}
```
Notice how the *port* property is not set in the production configuration. 

If you are running in production, and you try to access the *port* property, it will retrieve the *port* value from your default configuration, as it is not specified in the production.json.

Use the default configurations for common properties that occur between all your environments.
 
-----

## Implementation
In order to access your configurations, you need to do 3 things:
1. Require in the *config* dependency.
2. Check the existence of your configuration property using the *has* method.
3. Get the value of your configuration property using the *get* method.


If a configuration property is not found, and you try to access it, an error will be thrown. Therefore, it is good practice to check the existence of a property using the *has* method, as seen in the example below.

**Index.js**
```javascript
const config = require(‘config’);

// the NODE_ENV you set in your package.json scripts
console.log(process.env.NODE_ENV);

// Does the property exists? If so assign the values to variables, else assign null
const host = config.has(‘database.host’) ? config.get(‘database.host’) : null;
const port = config.has(‘database.port’) ? config.get(‘database.port’) : null;

if (!host || !port) {
  console.error(‘database configuration settings not set’);
}

console.log(`${host}:${port}`);
```

-----

## Conclusion
If you are running your applications in multiple environments, consider using this approach, especially if you have a lot of configurations to be set, e.g. database connections, email settings, remote logging configurations, etc.

Be aware that you **do not add any sensitive information to your source control** if you are using public repositories for your applications.

------
*<span>Header photo by <a href="https://unsplash.com/@adigold1?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Adi Goldstein</a> on <a href="/s/photos/music-studio?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>*