yenv
Manage environment stuff with YAML.
Installation
npm install --save yenv
Requires node v6.x or above.
Usage
Declaring variables in a file (eg. env.yaml
):
development:
PORT: 3000
DROP_DATABASE: true
production:
PORT: 80
DROP_DATABASE: false
Reading the file:
const yenv = require('yenv')
const env = yenv()
const env = yenv('env.yaml')
const env = yenv('env.yaml', { env: 'production' })
console.log(env.PORT)
console.log(env.DROP_DATABASE)
Environment variables
When a variable is defined in the environment, it will take precedence over
whatever was defined in the yaml-file.
This means that if your hosting provider (Heroku, Azure, whatever...) sets the
PORT
variable, then that's the variable that will be used.
You can disable this behavior by passing an empty object in the envObject
option.
const env = yenv('env.yaml', { envObject: {} })
Sensitive configuration should always be defined in the actual environment variables and not committed to source control!
Type coercion
yenv
will coerce values to the correct types.
For example, if you run your app with
PORT=80 ENABLE_EMAILS=true node app.js
Then typeof env.PORT
will be number
and typeof env.ENABLE_EMAILS
will be boolean
.
To disable this behavior, use yenv('env.yaml', { raw: true })
. This will make every value a string
.
Strict Mode
As of v2, Strict Mode is enabled by default. Strict Mode will throw an error when accessing unknown keys. This is possible thanks to Proxies. yenv
uses keyblade
for this.
The idea is to fail fast when a key does not exist.
To disable:
yenv('env.yaml', { strict: false })
This example shows the possible ways to configure Strict Mode:
yenv('env.yaml', {
strict: true,
optionalKeys: ['SOME_OPTIONAL_KEY', 'ANOTHER_ONE'],
logBeforeThrow: true
})
Composition
yenv
supports composing sections together. This is best illustrated with a code example.
base:
SOME_URL: 'http://google.com'
web:
PORT: 1338
development:
~compose: [base, web]
DEV_MODE: true
production:
~compose: development
PORT: 80
DEV_MODE: false
Importing
yenv
supports importing files recursively, with the importer winning in case of duplicate variables. Paths are resolved relative to the importing file!
There are 2 ways to import:
~require: [file1.yaml, file2.yaml]
- imports file1.yaml
and file2.yaml
. If a file does not exist, it throws an error.~import: [file1.yaml, file2.yaml]
- imports file1.yaml
and file2.yaml
. If a file does not exist, it acts as if it was empty.
Note: In v1.x
, ~import
would throw an error if the file does not exist. From v2.x
you can use ~require
for that behavior.
database.yaml
development:
DB_HOST: localhost
web.yaml
development:
PORT: 1337
production:
PORT: 80
env.yaml
~require: [database.yaml, web.yaml]
development:
PORT: 3000
const env = yenv()
env.DB_HOST
env.PORT
As mentioned earlier, in case of clashes the importer always wins. However, when it comes to 2 files being imported, the last one specified wins (but still not over the importer).
ProTip: You can use ~compose
on sections defined in imported files. Example:
stuff.yaml
cool-section:
STUFF: 'yenv is the best'
env.yaml
~require: stuff.yaml
development:
~compose: cool-section
CLI
yenv
ships with a neat CLI tool. Currently it only has one command: yenv print
.
yenv print [file] [env] [format]
lets you print your environment as JSON or a dotenv
-like list.
Example: printing the development
environment in env.yaml
as json
, sorted alphabetically (-s
= sort), and excluding the actual user environment (-f
= file only):
$ ./node_modules/.bin/yenv print env.yaml development json -f -s
{
"BOOLEAN": false,
"NUMBER": 1337,
"STRING": "hello dev world"
}
Example: same as above, but in raw
mode (-r
)
$ ./node_modules/.bin/yenv print env.yaml development json -f -s -r
{
"BOOLEAN": "false",
"NUMBER": "1337",
"STRING": "hello dev world"
}
Example: same as above, but in dotenv
format
$ ./node_modules/.bin/yenv print env.yaml development dotenv -f -s -r
BOOLEAN="false"
NUMBER="1337"
STRING="hello dev world"
Please see yenv print --help
for info.
TypeScript
Typings are available in lib/yenv.d.ts
and are set in package.json
.
To import yenv
in TypeScript:
import yenv from 'yenv'
Changelog
Please see CHANGELOG.md.
Author
Jeff Hansen - @Jeffijoe