GithubHelp home page GithubHelp logo

dwyl / env2 Goto Github PK

View Code? Open in Web Editor NEW
101.0 29.0 9.0 88 KB

:computer: Simple environment variable (from config file) loader for your node.js app

License: GNU General Public License v2.0

JavaScript 99.45% Shell 0.55%

env2's Introduction

env2 - environment variable loader

Build Status HitCount codecov.io Dependency Status devDependency Status npm

Why?

Environment variables are the best way of storing sensitive data like API Keys, Login Credentials and Database Passwords.

If you are new to environment variables please checkout our introduction for complete beginners: https://github.com/dwyl/learn-environment-variables

We needed a simple/reliable way of managing environment variables; and being able to share a configuration file among the team (without committing it to GitHub!) env2 is our solution.

What?

env2 allows you to store your environment variables in an env.json or a .env file which gets loaded when your app starts.

All the entries in the env file are exported as environment variables available as keys in the process.env object.

Works fine with build systems like webpack and browserify.
If you want to use it on the frontend, you will need some sort of filesystem shim

How?

Need help getting started? Join the chat at https://gitter.im/dwyl/chat

Create a .env File

We use (and recommend) .env files for environment configuration.
We call our file .env for cross-project consistency and .env is part of the official .gitignore from GitHub for NodeJS.
(but you can call your file what ever you like e.g: .environment)

A .env file is a very explicit way of listing environment variables without the extra syntax (potential human/input error) of a JSON file. It also allows for easier copy-pasting into the terminal (with an export keyword prepended to each line).

The format of a .env file is:

export DB_HOST=127.0.0.1
export DB_PORT=9200
export DB_USER=anon
export DB_PASS=password

Note the lack of spaces. You may leave blank lines and insert comments (starting with '#') to organise the file if you wish. Follow the instructions below for placing it in your .gitignore file.

Alternatively Create an env.json Configuration File

If you prefer to use .json instead of .env create a env.json file in your repo with the following format:

{
  "DB_HOST": "127.0.0.1",
  "DB_PORT": 9200,
  "DB_USER": "anon",
  "DB_PASS": "password"
}

Always .gitignore your configuration file

Always create your .env or env.json file in the root directory of your project and don't forget to add it to your .gitignoreto avoid accidentally committing your keys/passwords to GitHub where bad people can (will) steal your secrets!

e.g:

echo '.env' >> .gitignore

or

echo 'env.json' >> .gitignore

Install from NPM

Next install env2 from npm and save it to your package.json file:

npm install env2 --save

Use in your Code

Then in your script/module:

const env = require('env2')('./path-to-your/.env');

// your app goes here
console.log(process.env.DB_HOST); // "127.0.0.1"

now all the entries in your env.json or .env file are available as keys/values of the process.env Object which means you can use process.env.API_KEY or process.env.DB_PASSWORD in your script. (or what ever you have defined as entries in your env.json)

Env is synchronous; it loads all your configuration variables into the process.env object before app/script execution.


Do you want to Define Priority for Variables?

Do you want the ability to specify the priority which environment variables take precendence?
e.g: if you supply a command-line argument when running your script/app:

env=PROD API_KEY=token.dwyl.yolo node myapp.js

We have an open discussion on this: #1

At present, any environment variable defined in the environment where your app is running (or via command-line arguments) will take precendence over the same key in your env.json file ... if you prefer to have the option to specify the priority, please add a comment to the isssue: #1

Huh?

The Twelve Factor App section 3 states:

"Store config in the environment"

"An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc)".


Name ?

Q: Why is it called "env2"?
A: as the digit in the name suggests, there was/is an "env" (version 1): https://www.npmjs.com/package/env written by @dshaw sadly, it was never finished and has not been updated in 4 years ... We asked Dan if he would accept a Pull Request updating the package: dshaw/env#6 and he said he would accept it ... But after investing the time and submitting the pull request: dshaw/env#8 which updated the package to the latest version of Node/io.js and had tests with 100% coverage, the PR got ignored. see: https://twitter.com/dshaw/status/628237150253772801 Not that we're "impatient" but we need to move on with our code/lives. That's why we wrote env2.

We have since added better error handling and alternative file types, so env2 is can be considered the "New & Improved Version"

env2's People

Contributors

amilajack avatar des-des avatar dshaw avatar iteles avatar lennym avatar matjack1 avatar minaorangina avatar nelsonic avatar rjmk avatar simonlab avatar stevemao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

env2's Issues

How does module.parent.id work?

Apparently "[t]ypically this is the fully resolved filename" of the requiring module. But why would there be a 'node_modules' in that path when we require from a module in our project? How is the id property different from the filename property?

Readme requires tidy up.

Readme needs some help...

  • badges specifically codecov
    env2-badges

  • What section appears to have been affected by a PR/Merge conflict:
    env2-what-section-fail

Anything else you think could be improved. (please comment in this issue before making changes. thanks!)

Confusing: not actually 12 factor app config approach

env2 looks like a nice way to manage config, it's just not the 12fa way to manage config. As it currently stands, env2 doesn't actually allow you to take in config from the environment! :)

Unless I'm missing something, 12fa explicitly calls out the pattern in env2 as an anti-pattern, and provides good reasons to avoid it:

Another approach to config is the use of config files which are not checked into revision control, such as config/database.yml in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it’s easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific.

Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.

Should we convert the string values coming from .env files to JS primitives?

At the moment things like: ENV_TEST_VAR=true read from .env files are string values in process.env.ENV_TEST_VAR.

Converting to primitive types would also make things more consistent with the case of using .json files.

An idea would be to update the add_dot_env_line_to_json function to:

function add_dot_env_line_to_json (json, env_variable) {  
  var environment_parts = env_variable.split('=');  
  try {  
    json[environment_parts[0]] = JSON.parse(environment_parts[1]);
  }
  catch(e){
    json[environment_parts[0]] = environment_parts[1];
  } 
  return json;
}

Let me know if this would suffice or if there's a better solution and I'll create a PR.

Text Error

Should say instructions below, not above (with reference to the git ignore file)

Feature: Return env as Object

Story

As a person wanting to know which which environment variables were in the .env file
I would like to have the environment variables that were in the .env file returned as an Object
So that I can check if the var was loaded from a file or from another place.

Currently in our usage instructions: https://github.com/dwyl/env2#use-in-your-code
image
We hint at the possibility that the environment variables loaded by env2
are assigned to the env constant:

const env = require('env2')('./path-to-your/.env');

But reading the code we can see that no such Object is being returned:

env2/lib/env.js

Lines 57 to 60 in 15a8bd4

console.warn(msg);
return msg;
}
};

We could return the env on line 38 and it would (before the catch statement):

env2/lib/env.js

Lines 32 to 38 in 15a8bd4

var env = env_getter(filepath);
Object.keys(env).forEach(function(k) {
if(!process.env[k]) { // allow enviroment to take precedence over env.json
process.env[k] = env[k]; // only set if not set by environment
}
});
}

This would not alter the existing functionality of the package and would add this feature.

Streamline the Warning Message to avoid cluttering people's consoles!

At present we are printing out a large block of text:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error: ENOENT, no such file or directory '/home/travis/build/nelsonic/hits/config.env'
Your app has invoked env2 to load a configuration file but 
we could not find the configuration file: /home/travis/build/nelsonic/hits/config.env
please follow the instructions in the README to create your
env.json file and/or ensure that you give the correct path to it 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

This is an eyesore. lets fix it.

See:

  • env2/lib/env.js

    Lines 41 to 48 in a55f917

    var msg = '\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
    msg += e
    msg += '\nYour app has invoked env2 to load a configuration file but \n'
    msg += 'we could not find the configuration file: ' + filepath + '\n'
    msg += 'please follow the instructions in the README to create your\n'
    msg += 'env.json file and/or ensure that you give the correct path to it \n'
    msg += '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n'
    console.log(msg);
  • https://travis-ci.org/nelsonic/hits/builds/77237644#L213-L219

Error: Cannot find module 'env2'

If you're getting the following error:

State changed from starting to crashed
Error: Cannot find module 'env2'
at Function.Module._resolveFilename (module.js:469:15)

image

Why decache?

I don't think that we keep any state within env2 (apart from loading in path and fs; do they keep state?). Why is it necessary to decache the module?

Best practice for .env files with travis continuous deployment

Currently I am using travis's repository environment variables, and these work perfect for the build process. However, upon trying to deploy (to app engine managed vm's in my case) those are not carried over. I see everywhere people suggesting to use a .env file or similar methods to store them. This makes sense for local, but if I want them to be available for deployment what is the best method?

I have one idea, but not sure how secure or ideal it is.
Basically since I don't want my .env on a public git repository, I have it added to my .gitignore. However, this means when a travis build triggers, there will be no .env cloned into the build enforcement. However, in theory I could put all my env's on the travis repository settings, and then as part of the travis script before deployment, copy those values and generate a .env file each build that will be deployed (of course making sure not to display them in the build output). This way no one would have access (I think) and I could manage all my variables from the Travis web interface.

Concerns:

  1. Not sure how to go about accessing them, but I found this regarding travis access token which seems like it would work. (https://github.com/travis-ci/travis.rb#build-environment-variables)
  2. Assuming I can access them, what is the best way to output them to a temp file securely.

Thank you

Could use codecov key as good application example of env2

API keys may be a hard to understand example of using env2 because a lot of API applications would want more than local hosting. However in the case of using codecov, having your keys held locally would not cause problems for a live project and therefore could be a great example for env2.

Shameless plug

Hey @nelsonic, check out my defaultenv package I've created to solve the same problems -- I think you might like my approach:

  • It also allows you to use .js files to export default variables, so you can compute values dynamically if need be
  • It doesn't touch your app code -- instead it sets environment variables and then runs any command (e.g. defaultenv env/dev.js env/local.js -- npm start)

server can't find env2

Hi,

I am running a node express server, and have npm i --save env2 (it's in package.json and node_modules folder) but for some reason my sever keeps returning the error that it can't locate env2.
screen shot 2016-08-07 at 11 40 02

Do you know why this might be happening? Thanks!

Build error using webpack with env2

I npm installed env2 into a project to configure and access my environment variables. When I go to run the build with webpack, it keeps throwing an error:

WARNING in ./~/env2/lib/env.js
Critical dependencies:
31:69-76 require function is used in a way in which dependencies cannot be statically extracted
 @ ./~/env2/lib/env.js 31:69-76

ERROR in ./~/env2/package.json
Module parse failed: /node_modules/env2/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
|   "name": "env2",
|   "version": "2.0.6",
|   "description": "Environment Variable Loader",
 @ ./~/env2/lib/env.js 82:18-44

I included a plugin in the webpack.development.config.js file but the problem still persists. Plugin:

new webpack.DefinePlugin({
    'process.env.NODE_ENV': '"development"'
    })

I was wondering if anyone has had a similar issue?

env2 takes too much time load the variable

I am using env2 for loading env variable in nodejs+graphql setup and call the env loading function at the top of index.js file followed by schema for graphql server.

I am facing a problem where the env2 has not loaded the variable even after the method has been called like just after the line require('env2')(/path/to/env.json).

Document what is meant by `'./path-to-your/.env'`

(ie path begins with ./ or ../ and is relative to the package.json or run directory)

It is non-intuitive within a complex file structure whether env vars are failing to load due to the wrong path being included or due to:

�[1m�[43m�[30m WARNING: �[22m�[42m�[30m env2 was required to load an .env file: �[46m�[30m ./.env �[1m�[43m�[30m INVALID JSON! �[22m�[42m�[30m Please see: http://git.io/vG3UZ�[49m�[39m�[22m

Documenting the above would help.

Default file

Who has time to type env.json or .env? We should support a default file.

Environment variables with '=' won't work in '.env' files

If you are using a .env version of the file and have a '=' in the value of the environment variable, you will not get the correct value of the environment variable, because of the fact that only the second segment is used after splitting on '=' (

json[environment_parts[0]] = environment_parts[1];
).

I will fix this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.