Tuesday, 19 March, 2019 UTC


Summary

Environment variables. They make it easy to juggle between your local development, testing, staging, UAT, production or whatever other environments may have crept into your work flow. Passing around variables is easy enough but when you have more than a couple it can be a pain to remember them all. Instead of passing variables into your scripts individually, env-cmd makes it easy to group variables into an environment or “env” (I like to pronounce it like “envy”) file and pass them all to your script.

🐊 Alligator.io recommends ⤵

Learn Node, a video course by Wes Bos
ⓘ About this affiliate link
Safety First
It’s worth noting that while you may feel compelled to add environment and configuration files to your version control system, it’s generally considered a bad practice, since these files probably contain sensitive information.
To make sure you don’t accidentally add a file to your repository with logic credentials or keys, be sure to add the file to your .gitignore.
Getting Started
To get started with env-cmd, simply add it to your project with npm or yarn:
# via npm $ npm install env-cmd # via yarn $ yarn add env-cmd 
We can also create a basic environment file. Don’t worry it will append to your existing .env file if one exists:
echo 'reptile=alligator\ngreen=#008f68\nyellow=#fae042' >> .env 
And for good measure, we’ll create a script named gator.js to log our variables to the console:
console.log('NODE_ENV:', process.env.NODE_ENV); console.log('Reptile:', process.env.reptile); console.log('Green:', process.env.green); console.log('Yellow:', process.env.yellow); 
Basic Usage
The env-cmd package installs an executable script named env-cmd which can be called before your scripts to easily load environment variables from an external file.
Depending on your setup, you can reference env-cmd in a few different ways. The easiest and most compatible across package managers, is to setup a script within your package.json file:
{ "scripts": { "gator": "env-cmd .env node gator.js" } } 
The script expects an environment file as the first parameter and the command you would like to run after that.
If you would prefer to use env-cmd directly from the command-line, you can call it directly from node_modules:
$ ./node_modules/.bin/env-cmd .env node gator.js 
If you’re using a more recent npm version that supports npx, you can use that instead:
$ npx env-cmd .env node gator.js 
And if yarn is your bag, you can leverage it’s run command:
$ yarn run env-cmd .env node gator.js 
Regardless of how you choose to run the script, env-cmd will load up our .env file and our test script will report back the variables.
You may have noticed that the “Environment” value came back as undefined. That’s because we don’t have NODE_ENV defined in our .env file. Because env-cmd plays nice with the environment variables that are already set, we can still opt to pass in NODE_ENV before calling env-cmd:
$ NODE_ENV=development npx env-cmd .env node gator.js 
Supported File Formats
As mentioned, the first argument passed to env-cmd is the path and/or filename of your environment file. Typically, you would name the file .env and have it in either your project’s root or your home directory.
env-cmd supports files in either of the aforementioned locations, or you can simply reference the absolute path to the file.
Regardless of how you reference it, you have a wide variety of file formats available to store your environment variables.

JSON File

{ "reptile": "alligator", "green": "#008f68", "yellow": "#fae042" } 

JavaScript

module.exports = { reptile: 'alligator', green: '#008f68', yellow: '#fae042' }; 

INI File

reptile=alligator green-#008f68 yellow=#fae042 

RC File

The rc file format is special because it allows you to define multiple environments in a single JSON file and reference the environment by name instead of by file.
The “runcom” file is also special in that is must be named .env-cmdrc and present in the root of your project.
{ "development": { "NODE_ENV": "development", "reptile": "alligator", "green": "#008f68", "yellow": "#fae042", "otherVar1": 1 }, "staging": { "NODE_ENV": "staging", "reptile": "crocodile", "green": "#6db65b", "yellow": "#efbb35", "otherVar2": 2 }, "production": { "NODE_ENV": "production", "reptile": "turtle", "green": "#4aae9b", "yellow": "#dfa612", "otherVar3": 3 } } 
Then you can reference a single environment as such:
$ npx env-cmd development node gator.js 
You can even reference multiple environments, which will merge together each of the environment’s variables, with the last environment taking precedence if there are overlapping variables:
$ npx env-cmd development,staging,production node gator.js 
By specifying all three of our environments, each of the otherVar values will be set, with the rest of the variables being sourced from the final environment listed, production.
Graceful Fallbacks
Out of the box, env-cmd won’t put up much of a fight if the environment file you specify doesn’t exist. In that scenario you just won’t have access to any of the expected variables so you should be mindful of this when coding.
If you would prefer, env-cmd can attempt to load an .env file from the root of your project in situations when the specified file doesn’t exist. To do so, pass in the --fallback flag:
$ npx env-cmd .missing-env --fallback node gator.js 
Respecting Your Environment
Sometimes, you may want to favor the variables already set in the environment, instead of using the values in your .env file. To respect the existing environment variables, pass env-cmd the --no-override flag:
$ NODE_ENV=production npx env-cmd .env --no-override node gator.js 
In the above example, even if the .env file has the NODE_ENV variable defined, the value of NODE_ENV will remain as production.