4

Most people, and even the scaffold generated by the express command line tool, do this:

app.set(process.env.PORT || 3000);
...
...
...
http.createServer(app).listen(app.get('port'), ...);

Why? It seems superfluous to me when this works just fine and is less code:

http.createServer(app).listen(process.env.PORT || 3000, ...);

I'm sure there's a reason, I just can't seem to see what it is.

CatDadCode
  • 58,507
  • 61
  • 212
  • 318
  • possible duplicate of http://stackoverflow.com/questions/18864677/what-is-process-env-port-in-node-js – Manoj Gupta Jan 03 '14 at 04:49
  • 1
    This is definitely not a duplicate of that question. Same code samples !== same question. Neither the question nor the accepted answer are related to my question. – CatDadCode Jan 03 '14 at 04:51
  • 1
    Alex, you should rephrase your question as it looks like everyone thinks you are asking why ports are settable via environment variables, but that's not really what your question is about. – Peter Lyons Jan 03 '14 at 05:11
  • 3 votes to close because this question is "opinion based"? Sometimes I don't understand StackOverflow, lol. – CatDadCode Jan 04 '14 at 04:12
  • @PeterLyons I guess. I feel like the question is pretty obvious, but I'll try to be more specific next time. Thanks again. – CatDadCode Jan 04 '14 at 04:14

4 Answers4

5

I don't use app.set('port', process.env.PORT || 3000), personally. I agree with your intuition that doing so is unnecessary. I believe it is fueled by the false belief that other parts of your application need access to the port value. The only realistic use case I can see is wanting your test code to have access to the port. So in that case, it might be OK, but generally code that needs access to the port is usually (but not always) misguided, at least based on code bases I have seen and knowing in general how web stacks get connected. I suspect many well-meaning folks do this based on a vague "this might be useful at some point" notion.

The one benefit this does have if some other part of your code base does need to do app.get('port'), it won't need to duplicate the logic to fallback to a default value. So it's a good idea to keep your configuration handling and defaulting code in a single place, and it's also good to keep the amount of code in your app that uses process.env centralized and minimized. Specifically for the express port value, taking an environment variable which is already process global and copying it into the app object seems of dubious utility at best.

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
1

I have a second very different answer that may be more correct to answer "why to people leave it the same as the skeleton that was generated?"

Likely the truth is that nobody cares or pays much attention to startup code. There are no significant gains to be found there, because it all executes only once (ideally your server up time is 100.000%). People have better places to focus on performance gains.

Maybe it is a test to put something pointless into the generated skeleton and see how many people follow :)

Let the votes decide.

jdr5ca
  • 2,809
  • 14
  • 25
  • I didn't figure it was really having a performance impact. I was only curious as to why. I think you guys are right that the skeleton code is just trying to show off patterns. This is probably also the reason it includes a `user.list` route when I'm sure most apps would not need that either. – CatDadCode Jan 07 '14 at 16:03
0

You can run your node.js application using "PORT=80 node app.js " from command line so 3000 is used for testing and development purpose where the application runs on port 3000 port but when you deploy it to server you wont change the port instead use "PORT=80 node app.js" in command line this will make your app run on port 80.

Manoj Gupta
  • 578
  • 5
  • 10
  • You still don't understand my question. I know what the port and environment variable are for. What I don't understand is why we save the port as an express variable when the only requirement is that the port number get passed to app.listen. – CatDadCode Jan 03 '14 at 04:58
  • 1
    Its stored as environment variable so that you can access it from multiple location. If you pass like this http.createServer(app).listen(process.env.PORT || 3000, ...); when if you want to console.log("the port") you need to repeat the code. To avoid code repetition we stored it in environment variable. – Manoj Gupta Jan 03 '14 at 05:05
  • Right. I guess I was just wondering where else you'd ever need to do `app.get('port')`. – CatDadCode Jan 04 '14 at 04:10
  • 1
    It didn't help me. How many different ways do I have to say that? I downvoted you because the answer is completely irrelevant to the question. I did update your comment because that was closer to helpful, but still not helpful since someone else already gave a great answer that was upvoted and accepted. – CatDadCode Jan 07 '14 at 02:38
  • 1
    What an original idea :P – CatDadCode Jan 07 '14 at 16:01
0

The generated code is hinting at a pattern that separates the production of the application configuration and consumers of that configuration. With the code left as you show, it maybe looks pointless to separate the roles when there is only 1 consumer, and more so when there is only 1 data value.

Think forward to when you have more configuration information. You may also want to read configuration from the command line and/or a file, and that configuration will likely need to be consumed by multiple modules. To share the configuration, you will split out a module just to produce the configuration data and likely use a library for command line and environment parsing (NCONF for example).

So you might have a file config.js which is the producer of all the configuration and contains all the logic to generate the data:

// config.js
var nconf = require('nconf');

nconf.env().argv();  // read from environment table, then command line

nconf.defaults({
    'http': {'port': 3000},
    'mode': 'devel'
});

module.exports = nconf;

The main app.js only contains code that consumes the data:

// app.js
var nconf = require('./config.js');

//no line app.set('port'...)

http.createServer(app).listen(nconf.get('http:port'), 
  function(){console.log('Server listening on port ' + nconf.get('http:port')}
  );

This code sample is almost the exact same as app.set and app.get, but you might now say looks like a good pattern. I believe the code skeletons are hinting at the correct pattern: You should create and store the configuration in something all at one time and in one place, and then pull the data when later needed.

In other words, you don't want configuration logic scattered all through the code base. An example of the benefit can be shown by example. If I decided to read the configuration from a text file, my example above would change to:

nconf.env().file({file: 'appconfig.json'}).argv();

Nothing else changes.

jdr5ca
  • 2,809
  • 14
  • 25
  • That's my point though. I **don't** need to access that information anywhere else in the application. I've written quite a few express apps and I've never needed to pull the port from an express variable. I've only ever needed it in one place, `.listen`. – CatDadCode Jan 07 '14 at 02:40
  • 1
    You asked "most people do... why" I was trying to explain that people think about all the configuration the same as one set of data. I don't think "this bit of configuration has these rules and these uses". It all gets stored in something and then pulled from something. – jdr5ca Jan 07 '14 at 03:04