
Visitors are also reading...
Configuration Module for NodeJS
right now..
Removing background from image with imagemagick - revisited3 hours ago
When Play Framework 2.X Sass plugin says 'Sass compiler: ruby.exe: No such file or directory -- project_root/sass (LoadError)'11 hours ago
Resolving play!Framework's test migration problems21 hours ago
Quickly Solving NGNIX's "The system cannot find the path specified" in Windows24 hours ago
My list of useful Intellij Live Templates34 hours ago
removing backgrounds from images with 2 commands and a freeware39 hours ago
@OneToOne - does not force uniqueness!57 hours ago
Java classpath hell solution59 hours ago
Removing background from image with imagemagick - revisited60 hours ago
NodeJS is great but it lacks settings/configuration mechanisms.
Actually - I understand why it lacks it - configuration nowadays is written in JSON anyway.. so in node you just import it..
But there are some features you still want/need that do not exist yet.
Missing Features
- Overriding with another JS file
This means I want the same syntax to override the configuration. Some libraries suggest command line flags.. I do not like it. - Front-end support
I want to change configuration in a single place, and I want to be able to configure by front-end as well. - Fail to load if a required configuration is missing
Implementation
var publicConfiguration = {
"title": "Hello World"
"errorEmail": "null" // don't send emails if null
};
var privateConfiguration = {
"port":9040,
"adminUsername": undefined,
"adminPassword": undefined
}
var meConf = null;
try{
meConf = require("../conf/dev/meConf");
}catch( e ) { console.log("meConf does not exist. ignoring.. ")}
var publicConfigurationInitialized = false;
var privateConfigurationInitialized = false;
function getPublicConfiguration(){
if (!publicConfigurationInitialized) {
publicConfigurationInitialized = true;
if (meConf != null) {
for (var i in publicConfiguration) {
if (meConf.hasOwnProperty(i)) {
publicConfiguration[i] = meConf[i];
}
}
}
}
return publicConfiguration;
}
function getPrivateConfiguration(){
if ( !privateConfigurationInitialized ) {
privateConfigurationInitialized = true;
var pubConf = getPublicConfiguration();
if ( pubConf != null ){
for ( var j in pubConf ){
privateConfiguration[j] = pubConf[j];
}
}
if ( meConf != null ){
for ( var i in meConf ){
privateConfiguration[i] = meConf[i];
}
}
}
return privateConfiguration;
}
exports.sendPublicConfiguration = function( req, res ){
var name = req.param("name") || "conf";
res.send( "window." + name + " = " + JSON.stringify(getPublicConfiguration()) + ";");
};
var prConf = getPrivateConfiguration();
if ( prConf != null ){
for ( var i in prConf ){
if ( prConf[i] === undefined ){
throw new Error("undefined configuration [" + i + "]");
}
exports[i] = prConf[i];
}
}
return exports;
Explanations
- sendPublicConfiguration
- a route to send the public configuration that can be exposed in the front-end.
You should write something like
app.get("/backend/conf", require("conf.js").sendPublicConfiguration);
and then you can get the configuration by importing a scriptThe name decides the global variable name that will include the configuration. - undefined
- Means a configuration is required
- null
- Means the configuration is optional
- myConf
- The overrides file. The code above assumes it is under
app
folder and that meConf is underconf/dev
folder. You can easily change that so you can pass the overrides path when you require the module. - Overrides logic
- Private configuration simply takes all values from public configuration and then uses meConf for overrides.
Public configuration filters meConf and overrides only keys it already has.
This way we make sure nothing private is exposed.
Environment Support
Some people find it nice if they can run node with a flag stating if they are running in production or development.
I am not one of those people.
However, my code answers their needs as well.
You can have multiple meConf.js file
meConf.production.js
meConf.development.js
and so on, and import the right one using the environment flag.
You can also have a single meConf file which has fields for production, development and such and invoke the same logic.
meConf = require("../conf/dev/meConf")[environmentFlag];
Use it as you see fit.