I don't like the idea of sprinkling process.env all over the place and wanted to abstract it out a bit. I'm new to Node and know there must be a better way to do a few things.
- Not repeat the name 4 times (twice as a string and twice as a field)
- Any cleaner way to create properties and centralize existence checks than how I've done it? Mind you, I am trying to keep this Node 4.3.2 compatible sans Babel transpilers to keep it simple and working in AWS Lambda's NodeJs environment.
// module
module.exports = {
}
var configError = function (keyName) {
console.error("ExternalVars error! Could not load a value for: "+keyName);
process.exit(1);
}
// TODO: extract repeated function?
Object.defineProperty(module.exports, 'SAMPLE_SECRET', {
get: function() {
if (!process.env.SAMPLE_SECRET)
configError('SAMPLE_SECRET');
else
return process.env.SAMPLE_SECRET;
}
});
Object.defineProperty(module.exports, 'SAMPLE_SECRET_MORE', {
get: function() {
if (!process.env.SAMPLE_SECRET_MORE)
configError('SAMPLE_SECRET_MORE');
else
return process.env.SAMPLE_SECRET_MORE;
}
});
// usage example
var externalvars = require('./config/externalvars.js');
var sampleSecret = externalvars.SAMPLE_SECRET;
var sampleSecretMore = externalvars.SAMPLE_SECRET_MORE;
2 Answers 2
Disclaimer: since I'm not familiar with export/import realm, my suggestion below might be too naive and not work. If so, rather than only downvoting, thanks in advance for a little comment pointing me to a resource which would enlight how and why I'm wrong.
That's said, with merely my pure JS skills, here is how I'd work:
var keys = [
'SAMPLE_SECRET',
'SAMPLE_SECRET_MORE'
];
keys.forEach(function(keyName) {
Object.defineProperty(module.exports, keyName, {
get: function() {
if (!process.env[keyName]) {
console.error(
"ExternalVars error! Could not load a value for: " + keyName
);
process.exit(1);
} else {
return process.env[keyName];
}
}
});
});
-
\$\begingroup\$ This nicely removes the redundancy but for reasons I don't understand evaluates the getter without me calling it. For instance I set a value of process.env.SAMPLE_SECRET and then ask for it back and it tells me it can't find a value for SAMPLE_SECRET_MORE despite not asking for it. \$\endgroup\$ss2k– ss2k2016年12月04日 18:10:24 +00:00Commented Dec 4, 2016 at 18:10
-
\$\begingroup\$ @ss2k "evaluates the getter without me calling it": that's inherent to the way my proposed snippet works. And reading your comment I understand it doesn't exactly fits your need. In other words I believed you wanted to have something like a general configuration (hence my
keys
list), which would be early prepared for each registered key. Now you might consider replacing mykeys.forEach(function(keyName) {...});
byfunction(keyName) {...}
and invoke it when needed. BTW I realized my code was abruptly terminated, missing);
at the end. Corrected. \$\endgroup\$cFreed– cFreed2016年12月04日 21:00:33 +00:00Commented Dec 4, 2016 at 21:00 -
\$\begingroup\$ I wasn't able to replace as you had suggested without a syntax error. Can you write out your alternate version? \$\endgroup\$ss2k– ss2k2016年12月06日 00:29:19 +00:00Commented Dec 6, 2016 at 0:29
-
\$\begingroup\$ @ss2k My "alternate version" is merely what I wrote in my previous comment. In other words, embed the
Object.defineProperty()
statement in a function, sayprocessEnv(keyname)
, then call it when needed, e.g.processEnv(SAMPLE_SECRET)
. \$\endgroup\$cFreed– cFreed2016年12月06日 10:25:14 +00:00Commented Dec 6, 2016 at 10:25
Untested, but this should be equivalent to yours:
const requiredKeys = ['SAMPLE_SECRET', 'SAMPLE_SECRET_MORE']
const keyValues = requiredKeys.reduce((m,x) => {
if (!process.env[x]) {
console.error("ExternalVars error! Could not load a value for: "+keyName)
process.exit(1)
}
m[x] = process.env[x]
return m
}, {})
export default keyValues
Explore related questions
See similar questions with these tags.