process.env.NODE_ENV not matching 'development' no matter what - node.js

Just migrated on the latest Express, and stuck in something completely simple.
So, how is it possible, that this distilled example:
var env = process.env.NODE_ENV || 'development';
console.log(env);
if ('development' == env) {
console.log('im here');
}
else {
console.log('nah');
console.log(env);
}
with this server file runned as SET NODE_ENV=development & node server.js
gives output:
development
nah
development
instead of
development
im here
By the way, if I'll just manually set var env = 'development' then it work as it should be.
express 4.11.2, node 0.12.0, win8 x64.

I got same problem on windows mode. I'm not sure on linux. This problem caused by spaces between word "development" with "&" character. You can fix by remove spaces on your command. Example:SET NODE_ENV=development& node server.js

Your code looks fine, therefore the reason the equality test must be failing is because the strings aren't equal. Make sure you don't have any extra characters like spaces in your environment variable development string.

same problem, and I find using env.includes('development') instead is okay.

I tried going with the recommendations here but nothing managed to rid me of the wayward space.
so I just trim the variable where it needs to be used:
require('dotenv').config();
const configSet = () => {
const envData = process.env;
console.log('configSet -> process.env', envData);
console.log('configSet -> envData.NODE_ENV', envData.NODE_ENV);
const prodOrDevMode = envData.NODE_ENV.trim();
switch (prodOrDevMode) {
case 'development':
envData.TABLE_NAME = envData.DB_TABLE_DEV;
return envData;
case 'production':
envData.TABLE_NAME = envData.DB_TABLE_PROD;
return envData;
default:
throw new Error('Incorrect env setting');
}
};
const config = configSet();
module.exports = { config };
I'd appreciate any feedback on this in particular if this may cause issues

Related

process.env is an empty object

I am using Gulp / Browserify / Node on Windows, and I want to only include debugging information when in development.
I have a dependant task that is being run before anything else
gulp.task('set-dev-node-env', function() {
process.env.NODE_ENV = 'development'
}
Yet when I try and access this in my code I am finding process.env is an empty object.
console.log("process.env",process.env)
How can I get this to work?
I found a solution was to use envify
var envify = require('envify/custom')
and add it as a transform on my browserify() call
.transform(envify({
NODE_ENV: 'development'
}))

gulp.js+browserify: Dynamically generate development-specific files

I have an application that has some development-specific debugging code in it. Currently, all development code is guarded by a variable called dev at the top of the file. Here's an example of what my app does:
var dev = true;
if (dev) {
console.log("Hello developer");
} else {
console.log("Hello production");
}
When I go to deploy my application, I have to manually change the dev variable form true to false. This sucks.
I'm in the middle of migrating from hand-rolled builds to gulp.js and I want to solve this development vs. production build problem cleanly. I'm thinking about the following:
// Inside main.js
var dev = require('./isdev');
if (dev) //...
// Inside isdev.js:
module.exports = true;
Now, when I build for production, instead of manually setting the dev flag to false, I want to replace isdev.js from module.exports = true; to module.exports = false;. My specific question is, how do I automate gulp such that gulp development produces a file with dev = true and gulp production produces a file with dev = false.
Here's an update to those who are curious.
First, I have an options.js:
exports.dev = false;
I also have a options_dev.js:
exports.dev = true;
Inside of gulpfile.js, I have the following code that parses input arguments:
// Parse the arguments. Use `gulp --prod` to build a production extension
var argv = parseArgs(process.argv.slice(2));
var dev = !argv['prod']; // Whether to build a development extension or not
Finally, when I pipe to browserify, I have the following:
var resolve = require('browser-resolve');
// ...
.pipe(browserify({
debug: dev,
resolve: function(pkg, opts) {
// Replace options.js with options_dev.js if this is a dev build
if (dev) {
opts.modules['./options'] = 'src/options_dev.js';
}
return resolve.apply(this, arguments);
}
}))
The magic happens by using a custom resolve function, dynamically swapping ./options with options_dev for development builds. The browserify docs say:
You can give browserify a custom opts.resolve() function or by default it uses browser-resolve.
When we run gulp, we build a development version. When we run gulp --prod, we build a production version. The value of require('./options').dev allows us to dynamically change things like server endpoints, etc. Cool!
The way that I've seen this done is to set the environment variable on the command line before the execution command. An example of doing this with the Node.JS CLI (in a bash-like environment) would be:
ENV=dev node
> process.env.ENV
'dev'
Then in your code, you could do:
var dev = process.env.ENV === 'dev'
So with gulp, you could use:
ENV=dev gulp <task name>
I tested this out with the following snippet, and it works:
gulp.task('dev', function(){
if (process.env.ENV === 'dev')
console.log("IT WORKED");
else
console.log("NO DICE");
});
Edit:
You can write out the environment to the file isdev right before building:
var fs = require('fs');
gulp.task('build', function(){
if (process.env.ENV === 'dev')
fs.writeFileSync('isdev', 'module.exports = true');
else
fs.writeFileSync('isdev', 'module.exports = false');
// kick off build
});
Now, the correct value will be present in isdev for any require call in the built bundle. You could extend this to other specified environments as well (or to other configuration flags).

Meteor: How to separate local environment from production?

I have two pieces of code: one that must only be run in a local environment and the other in production. What is the best way to do that in Meteor?
You can check do
(server side)
var isDevelopment = function() {
var i = WebApp.clientProgram.manifest.length;
while(i--) {
if('sourceMap' in WebApp.clientProgram.manifest[i]) return true;
}
return false;
}
if(isDevelopment()) {
console.log("Dev mode");
}else{
console.log("Production");
}
The idea is to check for JS Source Maps, which are only available in dev mode. This should work out of the box with your meteor app without any special configuration.
I prefer to set an environment variable which the server can read. For example:
$ METEOR_ENV="production" meteor
Then on the server:
if (process.env.METEOR_ENV === 'production') {
// production code here
} else {
// dev code here
}
If you have only two states, you could assume !production = dev.
Use this package and you will haveMeteor.isdevelopment only in development. There is other packages out there too that do the same thing but differently. this is the simplest

nodejs config module optimist or nconf?

I've just started writing my first app with NodeJS and I must say it's a pleasure learning how to work with :)
I've reached the point where I'm making some configuration before starting the server, and I would like to load the config from a config.json file.
I have found a few ways so far, either request that json file and leaver node require parse it, use a config.js file and export my config, use nconf, which seems pretty easy to use, or the last option I've seen is using optimist which I thought it would be better than ncond. Though I'm starting to think that the latter, optimist, can only be used for parsing arguments from the node cli.
So I'm asking here, can I use node optimist to get my config from a file, or, if not, should I use nconf ? Or maybe, there's something even better and lightweight out there that I don't know of ? (my options at this point are pretty vague, since I'm not sure if at some point I would like to parse any config from the cli).
I use a config.js file like this:
var config = {}
config.web = {};
config.debug = {};
config.server_name = 'MyServerName';
config.web.port = process.env.WEB_PORT || 32768;
config.debug.verbositylevel = 3;
module.exports = config;
then i can just call config variables like this:
var port = config.web.port;
I find it much easier to maintain like this. Hope that helps you.
I use dotenv. It's as easy as:
var dotenv = require('dotenv');
dotenv.load();
Then you just create a .env file with your configuration settings.
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
Disclaimer: I'm the creator, and didn't find the config.json file approach useful in production environments. I prefer getting configuration from my environment variables.
6 years later and the answer should have been: Use Nconf. it's awesome.
//
// yourrepo/src/options.js
//
const nconf = require('nconf');
// the order is important
// from top to bottom, a value is
// only stored if it isn't found
// in the preceding store.
// env values win all the time
// but only if the are prefixed with our appname ;)
nconf.env({
separator: '__',
match: /^YOURAPPNAME__/,
lowerCase: true,
parseValues: true,
transform(obj) {
obj.key.replace(/^YOURAPPNAME__/, '');
return obj;
},
});
// if it's not in env but it's here in argv, then it wins
// note this is just passed through to [yargs](https://github.com/yargs/yargs)
nconf.argv({
port: {
type: 'number'
},
})
// if you have a file somewhere up the tree called .yourappnamerc
// and it has the json key of port... then it wins over the default below.
nconf.file({
file: '.yourappnamerc'
search: true
})
// still not found, then we use the default.
nconf.defaults({
port: 3000
})
module.exports = nconf.get();
then in any other file
const options = require('./options');
console.log(`PORT: ${options.port}`);
now you can run your project like :
$ yarn start
# prints PORT: 3000
$ YOURAPPNAME__PORT=1337 yarn start
# prints PORT: 1337
$ yarn start --port=8000
# prints PORT: 8000
$ echo '{ "port": 10000 }' > .yourappnamerc
$ yarn start
# prints PORT: 10000
and if you forget what options you have
$ yarn start --help
# prints out all the options

Using environment specific configuration files in Node.js

Unlike Rails, there doesn't seem to be an accepted way of loading environment specific config files in Node.js.
Currently I'm using the following:
config/development.js and config/production.js:
module.exports = {
'db': 'mongodb://127.0.0.1/example_dev',
'port': 3002
};
Followed by the following at the top of my app.js file:
var config = require('./config/' + process.env.NODE_ENV + '.js');
This pattern works pretty well, however it forces me to pass along this config file to any modules that need it. This gets kind of clunky, for instance:
var routes = require('./routes')(config);
.. and in routes/index.js:
modules.export = function(config) {
this.index = function...
this.show = function...
};
Etc, etc. The module pattern just seems to be pretty clunky when dealing with something that should be global, like configuration settings. I could require the configuration file at the top of every file that needs it as well, but that doesn't seem ideal either.
Does anyone have a best practice for including a configuration file and making it globally available?
You could just attach it to the global process object:
app.js:
var config = require('./config/' + process.env.NODE_ENV + '.js');
process.config = config;
aywhere else in your app
console.log(process.config);
Yes, it's a bit dangerous in that it can get overwritten anywhere, but it's still a pretty simple approach.

Resources