• Stars
    star
    104
  • Rank 330,604 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 9 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Environment management for Node using YAML.

yenv

npm version Dependency Status Build Status Coverage Status

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-specific settings.
development:
  PORT: 3000
  DROP_DATABASE: true
# Production-specific settings.
production:
  PORT: 80
  DROP_DATABASE: false

Reading the file:

const yenv = require('yenv')

// Default filename is env.yaml.
const env = yenv()

// You can call it with a filename, too.
const env = yenv('env.yaml')

// The top-level element in the YAML-file is used to
// read the correct set of variables. The value is grabbed
// from `process.env.NODE_ENV`. To explicitly specify it, use:
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:

// These are all default values (except `optionalKeys`).
yenv('env.yaml', {
  /**
   * If `true` (default), wraps the result in `keyblade` which protects
   * against undefined keys.
   */
  strict: true,
  /**
   * If `strict` is enabled, allows these keys to not exist.
   */
  optionalKeys: ['SOME_OPTIONAL_KEY', 'ANOTHER_ONE'],
  /**
   * If `strict` is enabled, when an unknown key is found, calls this before throwing.
   * First parameter is the message, second is the missing key.
   * If `true`, uses `console.log`.
   */
  logBeforeThrow: true // can also be a function
})

Composition

yenv supports composing sections together. This is best illustrated with a code example.

# Some base config..
base:
  SOME_URL: 'http://google.com'

# Another section, related to the web config..
web:
  PORT: 1338

# Development config uses base config
development:
  # We can compose more than one at a time.
  ~compose: [base, web]
  # Declare additional settings..
  DEV_MODE: true

# Production config composes and overrides other sections
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 # This wins over web.yaml because this is the importer.
const env = yenv()
env.DB_HOST // "localhost"
env.PORT // 3000

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

More Repositories

1

awilix

Extremely powerful Inversion of Control (IoC) container for Node.JS
TypeScript
2,999
star
2

typesync

Install missing TypeScript typings for dependencies in your package.json.
TypeScript
1,390
star
3

koa-es7-boilerplate

A boilerplate for writing Koa 2 apps in ES7 with Babel.
JavaScript
272
star
4

mobx-task

Makes async function state management in MobX fun.
TypeScript
237
star
5

messageformat.net

ICU MessageFormat implementation for .NET.
C#
148
star
6

awilix-koa

Awilix helpers/middleware for Koa 2
TypeScript
129
star
7

koa-respond

Koa middleware that adds useful methods to the context.
JavaScript
102
star
8

awilix-express

Awilix helpers/middleware for Express
TypeScript
101
star
9

libx

Collection + Model infrastructure for MobX applications.
TypeScript
99
star
10

httpclientgoodies.net

Useful utilities for the .NET HttpClient.
C#
62
star
11

snicket

Stream Store based on Postgres for Node.JS
TypeScript
40
star
12

screengun

A simple screen recorder for Windows based on ffmpeg
C#
39
star
13

fejl

Error-making utility for Node apps.
TypeScript
35
star
14

logpipe-server

The Logpipe server.
JavaScript
30
star
15

awilix-router-core

Reusable building blocks for writing Awilix router adapters for HTTP frameworks.
TypeScript
25
star
16

validx

Validation library for MobX.
TypeScript
23
star
17

keyblade

Fail fast when accessing undefined properties on objects.
JavaScript
14
star
18

npm-module-boilerplate

A boilerplate for authoring npm modules, with tests and linting.
JavaScript
10
star
19

skadi

A simple object validator/sanitizer based on `is-my-json-valid`.
JavaScript
9
star
20

deltio

A Google Cloud Pub/Sub emulator alternative, written in Rust.
Rust
8
star
21

dration

Duration utilities for JavaScript using primitive types.
TypeScript
6
star
22

icebug

A wrapper around node-inspector and nodemon.
JavaScript
4
star
23

jQuery-Validator.Knockout

KnockoutJS bindings for my jQuery-Validator.
JavaScript
4
star
24

bristol-sentry

Sentry integration for the Bristol logger
JavaScript
3
star
25

smid

Catches errors and returns them. Useful for unit testing.
TypeScript
3
star
26

baconpi-web

BaconPi Web Frontend + Backend
JavaScript
3
star
27

ts-module-boilerplate

TypeScript module boilerplate for Node packages
TypeScript
3
star
28

posish

A tool that makes counting string lines, columns and indexes awesome. Useful for writing parser tests.
JavaScript
2
star
29

total-rename

Utility to replace strings in files and paths.
Go
2
star
30

purge

Windows utility for deleting a directory tree with long paths.
C#
1
star
31

chilli

Rename files to sort-friendly numbers
F#
1
star
32

jQuery-Validator

A formless validation plugin for all kinds of validation - even your own!
JavaScript
1
star