Skip to content

Commit c1e0054

Browse files
authored
Use dotenv for configuration management (kunalkapadia#302)
1 parent 3e520a8 commit c1e0054

16 files changed

+71
-46
lines changed

.env.example

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
NODE_ENV=development
2+
PORT=4040
3+
JWT_SECRET=0a6b944d-d2fb-46fc-a85e-0295c986cd9f
4+
MONGO_HOST=mongodb://localhost/express-mongoose-es6-rest-api-development
5+
MONGO_PORT=27017

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ node_modules
4646

4747
# Optional REPL history
4848
.node_repl_history
49+
50+
# .env
51+
.env

.istanbul.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
verbose: false
22
instrumentation:
3-
excludes: ['dist/**', 'coverage/**', 'gulpfile.babel.js', 'config/env/development.js', 'config/env/production.js']
3+
excludes: ['dist/**', 'coverage/**', 'gulpfile.babel.js']
44
include-all-sources: true
55
reporting:
66
print: summary
@@ -22,4 +22,4 @@ check:
2222
statements: 50
2323
lines: 50
2424
branches: 30
25-
functions: 20
25+
functions: 20

config/config.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Joi from 'joi';
2+
3+
// require and configure dotenv, will load vars in .env in PROCESS.ENV
4+
require('dotenv').config();
5+
6+
// define validation for all the env vars
7+
const envVarsSchema = Joi.object({
8+
NODE_ENV: Joi.string()
9+
.allow(['development', 'production', 'test', 'provision'])
10+
.default('development'),
11+
PORT: Joi.number()
12+
.default(4040),
13+
MONGOOSE_DEBUG: Joi.boolean()
14+
.when('NODE_ENV', {
15+
is: Joi.string().equal('development'),
16+
then: Joi.boolean().default(true),
17+
otherwise: Joi.boolean().default(false)
18+
}),
19+
JWT_SECRET: Joi.string().required()
20+
.description('JWT Secret required to sign'),
21+
MONGO_HOST: Joi.string().required()
22+
.description('Mongo DB host url'),
23+
MONGO_PORT: Joi.number()
24+
.default(27017)
25+
}).unknown()
26+
.required();
27+
28+
const { error, value: envVars } = Joi.validate(process.env, envVarsSchema);
29+
if (error) {
30+
throw new Error(`Config validation error: ${error.message}`);
31+
}
32+
33+
const config = {
34+
env: envVars.NODE_ENV,
35+
port: envVars.PORT,
36+
mongooseDebug: envVars.MONGOOSE_DEBUG,
37+
jwtSecret: envVars.JWT_SECRET,
38+
mongo: {
39+
host: envVars.MONGO_HOST,
40+
port: envVars.MONGO_PORT
41+
}
42+
};
43+
44+
export default config;

config/env/development.js

-9
This file was deleted.

config/env/index.js

-10
This file was deleted.

config/env/production.js

-8
This file was deleted.

config/env/test.js

-8
This file was deleted.

config/express.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import expressValidation from 'express-validation';
1111
import helmet from 'helmet';
1212
import winstonInstance from './winston';
1313
import routes from '../server/routes/index.route';
14-
import config from './env';
14+
import config from './config';
1515
import APIError from '../server/helpers/APIError';
1616

1717
const app = express();

gulpfile.babel.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ const plugins = gulpLoadPlugins();
88

99
const paths = {
1010
js: ['./**/*.js', '!dist/**', '!node_modules/**', '!coverage/**'],
11-
nonJs: ['./package.json', './.gitignore'],
11+
nonJs: ['./package.json', './.gitignore', './.env'],
1212
tests: './server/tests/*.js'
1313
};
1414

1515
// Clean up dist and coverage directory
1616
gulp.task('clean', () =>
17-
del.sync(['dist/**', 'coverage/**', '!dist', '!coverage'])
17+
del.sync(['dist/**', 'dist/.*', 'coverage/**', '!dist', '!coverage'])
1818
);
1919

2020
// Copy non-js files to dist

index.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import mongoose from 'mongoose';
22
import util from 'util';
3-
import config from './config/env';
3+
4+
// config should be imported before importing any other file
5+
import config from './config/config';
46
import app from './config/express';
57

68
const debug = require('debug')('express-mongoose-es6-rest-api:index');
@@ -12,7 +14,8 @@ Promise = require('bluebird'); // eslint-disable-line no-global-assign
1214
mongoose.Promise = Promise;
1315

1416
// connect to mongo db
15-
mongoose.connect(config.db, { server: { socketOptions: { keepAlive: 1 } } });
17+
const mongoUri = `${config.mongo.host}:${config.mongo.port}`;
18+
mongoose.connect(mongoUri, { server: { socketOptions: { keepAlive: 1 } } });
1619
mongoose.connection.on('error', () => {
1720
throw new Error(`unable to connect to database: ${config.db}`);
1821
});

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "express-mongoose-es6-rest-api",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "A Boilerplate application for building REST APIs using express, mongoose in ES6 with code coverage",
55
"author": "Kunal Kapadia <[email protected]>",
66
"main": "index.js",
@@ -47,6 +47,7 @@
4747
"cookie-parser": "1.4.3",
4848
"cors": "2.8.1",
4949
"debug": "^2.4.5",
50+
"dotenv": "^4.0.0",
5051
"express": "4.14.0",
5152
"express-jwt": "5.1.0",
5253
"express-validation": "1.0.1",

server/controllers/auth.controller.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import jwt from 'jsonwebtoken';
22
import httpStatus from 'http-status';
33
import APIError from '../helpers/APIError';
4-
import config from '../../config/env';
4+
import config from '../../config/config';
55

66
// sample user, used for authentication
77
const user = {

server/routes/auth.route.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import validate from 'express-validation';
33
import expressJwt from 'express-jwt';
44
import paramValidation from '../../config/param-validation';
55
import authCtrl from '../controllers/auth.controller';
6-
import config from '../../config/env';
6+
import config from '../../config/config';
77

88
const router = express.Router(); // eslint-disable-line new-cap
99

server/tests/auth.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import httpStatus from 'http-status';
33
import jwt from 'jsonwebtoken';
44
import chai, { expect } from 'chai';
55
import app from '../../index';
6-
import config from '../../config/env';
6+
import config from '../../config/config';
77

88
chai.config.includeStack = true;
99

yarn.lock

+4
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,10 @@ [email protected]:
13971397
version "1.0.0"
13981398
resolved "https://registry.yarnpkg.com/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz#5932890dc9f4e2f19e5eb02a20026e5e5efc8f58"
13991399

1400+
dotenv@^4.0.0:
1401+
version "4.0.0"
1402+
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
1403+
14001404
14011405
version "0.0.2"
14021406
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"

0 commit comments

Comments
 (0)