A smarter dotenv for Node.js

If you’ve been coding in Node.js for some time, it’s likely that you’ve used or at least heard of dotenv.

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

It’s one of the must-have libraries whi…


This content originally appeared on DEV Community and was authored by Tim Wong

If you've been coding in Node.js for some time, it's likely that you've used or at least heard of dotenv.

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

It's one of the must-have libraries which I install in nearly all of my projects, until I published typed-dotenv last year.

Demo

Instead of explaining the difference between dotenv and typed-dotenv, let's feel it by seeing how we write my-api-client.js differently.

dotenv

/* my-api-client.js */

const { config } = require('dotenv');
const HttpClient = require('./http-client');

config();

const required = ['MY_API_HOST', 'MY_API_KEY'];
for (const key of required) {
  if (!process.env[key]) {
    throw new Error(`Missing the environment variable "${key}"`);
  }
}

const config = {
  host: process.env.MY_API_HOST,
  apiKey: process.env.MY_API_KEY,
  timeout: parseInt(process.env.MY_API_TIMEOUT) || 5000,
  keepAlive: process.env.MY_API_KEEP_ALIVE === 'true',
};

module.exports = new HttpClient(config);

This is the common way we use dotenv. The code isn't bad right? But can it be better?

typed-dotenv

/* my-api-client.js */

const { config } = require('typed-dotenv');
const HttpClient = require('./http-client');

const { error, env } = config({ rename: { enabled: true } });

// Errors regarding missing required variables, or other config issues.
if (error) {
  throw error;
}

module.exports = new HttpClient(env.myApi);

All in a sudden, the custom validation and data conversion are gone. The code is a lot simpler!

It is basically done for the coding side, but we need one more file - .env.template. This file is for typed-dotenv to do all the hard work, and more importantly, serves as a documentation for others to overview all env-var in one place.

### .env.template ###

##
# @required {string}
MY_API__HOST=

##
# @required {string}
MY_API__API_KEY=

##
# @optional {number} = 5000
MY_API__TIMEOUT=

##
# @optional {boolean} = false
MY_API__KEEP_ALIVE=

Note that the variable names are using double underscores. This is the magic where typed-dotenv turns the variables into the following structure, so you can supply it to new HttpClient(env.myApi) directly.

{
  "myApi": {
    "host": "...",
    "apiKey": "...",
    "timeout": 5000,
    "keepAlive": false
  }
}

Summary

By composing the .env.template file, typed-dotenv can...

  1. convert the env-vars into the desired types (e.g. number, boolean, json, etc.); and
  2. validate if the required env-vars are defined; and
  3. assign default values to the optional env-vars; and
  4. rename the env-vars to fit your purpose; and
  5. document the env-vars in one place; and
  6. ...many more.

If you are interested, please give it a try! Comments are welcome.

GitHub: https://github.com/cytim/nodejs-typed-dotenv
NPM: https://www.npmjs.com/package/typed-dotenv

My Personal Recipe

Last but not least, I found that it's usually helpful to wrap typed-dotenv in a config.js module.

/* config.js */

const { get } = require('lodash');
const { config } = require('typed-dotenv');

const { error, env } = config({
  unknownVariables: 'remove',
  rename: { enabled: true },
});

if (error) {
  throw error;
}

exports.getConfig = (path) => {
  const data = path ? get(env, path) : env;

  if (data === undefined) {
    throw new Error(`The config path does not exist: ${path}`);
  }

  return data;
};

Then you can use it like getConfig('path.to.some.config').

Hope you like it. :)


This content originally appeared on DEV Community and was authored by Tim Wong


Print Share Comment Cite Upload Translate Updates
APA

Tim Wong | Sciencx (2021-10-18T16:46:23+00:00) A smarter dotenv for Node.js. Retrieved from https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/

MLA
" » A smarter dotenv for Node.js." Tim Wong | Sciencx - Monday October 18, 2021, https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/
HARVARD
Tim Wong | Sciencx Monday October 18, 2021 » A smarter dotenv for Node.js., viewed ,<https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/>
VANCOUVER
Tim Wong | Sciencx - » A smarter dotenv for Node.js. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/
CHICAGO
" » A smarter dotenv for Node.js." Tim Wong | Sciencx - Accessed . https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/
IEEE
" » A smarter dotenv for Node.js." Tim Wong | Sciencx [Online]. Available: https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/. [Accessed: ]
rf:citation
» A smarter dotenv for Node.js | Tim Wong | Sciencx | https://www.scien.cx/2021/10/18/a-smarter-dotenv-for-node-js/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.