In the code below, I am building a NODE_ENV-sensitive config object from environment variables.
let username
let password
let cluster
let hosts
let databaseName
let replicaSet
if (process.env.NODE_ENV === 'production') {
username = process.env.ATLAS_HUB_USERNAME
password = process.env.ATLAS_HUB_PASSWORD
cluster = process.env.ATLAS_CLUSTER
hosts = process.env.ATLAS_HOSTS
databaseName = process.env.ATLAS_DATABASE
replicaSet = process.env.ATLAS_REPLICA_SET
} else {
username = process.env.MONGO_HUB_USERNAME
password = process.env.MONGO_HUB_PASSWORD
cluster = process.env.MONGO_CLUSTER
hosts = process.env.MONGO_HOSTS
databaseName = process.env.MONGO_DATABASE
replicaSet = process.env.MONGO_REPLICA_SET
}
const config = { username, password, cluster, hosts, databaseName, replicaSet }
In this new age of fancy spread and rest operators, I hate polluting my files with code like this which repeat the same variable name multiple times and uses let
instead of const
for the wrong reasons, all for something simple and frequent. I could use the ternary operator to get something way better:
const config = {
username: process.env.NODE_ENV === 'production' ? process.env.ATLAS_HUB_USERNAME : process.env.MONGO_HUB_USERNAME,
password: process.env.NODE_ENV === 'production' ? process.env.ATLAS_HUB_PASSWORD : process.env.MONGO_HUB_PASSWORD,
cluster: process.env.NODE_ENV === 'production' ? process.env.ATLAS_CLUSTER : process.env.MONGO_CLUSTER,
hosts: process.env.NODE_ENV === 'production' ? process.env.ATLAS_HOSTS : process.env.MONGO_HOSTS,
databaseName: process.env.NODE_ENV === 'production' ? process.env.ATLAS_DATABASE : process.env.MONGO_DATABASE,
replicaSet: process.env.NODE_ENV === 'production' ? process.env.ATLAS_REPLICA_SET : process.env.MONGO_REPLICA_SET
}
But even this seems one step short of what modern js should be able to do. I'd now like to get rid of the repeated process.env.NODE_ENV
, I just can't figure out how (apart from creating a new const with a shorter name). If I had a magic wand, I'd write something along the following lines:
const config = ({
username: [process.env.MONGO_HUB_USERNAME, process.env.ATLAS_HUB_USERNAME],
password: [process.env.MONGO_HUB_PASSWORD, process.env.ATLAS_HUB_PASSWORD],
cluster: [process.env.MONGO_CLUSTER, process.env.ATLAS_CLUSTER],
hosts: [process.env.MONGO_HOSTS, process.env.ATLAS_HOSTS],
databaseName: [process.env.MONGO_DATABASE, process.env.ATLAS_DATABASE],
replicaSet: [process.env.MONGO_REPLICA_SET, process.env.ATLAS_REPLICA_SET]
}).*[new Number(process.env.NODE_ENV === 'production')]
But I don't, and it's not even all that great, sooo, any suggestions?
I thought of using a function, like below, but this just introduces another dependency you need to internalize for a simple batch conditional assignment operation... And if the function is in-line, there is duplication across files and it's frankly just confusing.
function fromEach (obj, key) {
const final = {}
Object.keys(obj).forEach((k) => {
final[k] = obj[k][key]
})
return final
}
const config = fromEach({
username: [process.env.MONGO_HUB_USERNAME, process.env.ATLAS_HUB_USERNAME],
password: [process.env.MONGO_HUB_PASSWORD, process.env.ATLAS_HUB_PASSWORD],
cluster: [process.env.MONGO_CLUSTER, process.env.ATLAS_CLUSTER],
hosts: [process.env.MONGO_HOSTS, process.env.ATLAS_HOSTS],
databaseName: [process.env.MONGO_DATABASE, process.env.ATLAS_DATABASE],
replicaSet: [process.env.MONGO_REPLICA_SET, process.env.ATLAS_REPLICA_SET]
}, new Number(process.env.NODE_ENV === 'production'))
Note: I use new Number(process.env.NODE_ENV === 'production')
in these examples, but I don't like it, feel free to propose something better!