January 4, 2014

Things I wish I knew about Node + Express before making my first website with it

Develop with nodemon, deploy with forever

nodemon vs forever? More like nodemon AND forever! nodemon is live reload for Node apps. When it detects a file in your application has changed, it will restart your application for you. It does not require much configuration, and will save you many keystrokes and mouse clicks. My typical nodemon command looks like:

nodemon app.js --debug

It can also be used as part of a grunt command with grunt-nodemon.

Apps that restart well with nodemon will work better with forever. When your live application crashes despite all your unit tests passing, forever will automatically restart it. It offers more flexible logging, and can manage several nodejs apps at once. You can start an app with forever with a command like this:

forever start app.js

Waking up in the morning to see your Apache logs full of PHP errors isn’t fun, but the site may still be up and running. Waking up in the morning to see 1 error in your Node app brought the site down for hours is less fun. forever can help with that.

How to set environment variables

Environment variables are a good place to store private things like passwords and keys needed by your app. You don’t want those in your source code. I grew up using Windows, and didn’t know this method. Try running this command with nodejs installed:

NODE_ENV=debug DB_URL=mongodb://urlhere.ca STUFF=great node

This will start nodejs with environment variables named NODE_ENV, DB_URL, and STUFF set and ready to use. Type this command into the nodejs console next:

console.log(process.env);

You’ll see ENV, DB_URL, and STUFF included in the list other environment variables like PATH, ready to be used by your application. The variables will go away when the nodejs process ends. I find this very helpful when working on Heroku-hosted apps. Heroku uses environment variables for storing authentication info for many add-ons, and being able to duplicate those settings locally while developing brings me one step closer to matching their environment.

I have tested this out with nodemon and forever on Windows with the Git terminal as well as Linux, and it works in all cases.

NODE_ENV=production DB_URL=mongodb://urlhere.ca nodemon index.js

node-inspector will save you time

Look at this thing!

Breakpoints

Debugging Screenshot

Better logging

Console Screenshot

All for Node! You can’t want to use console.log() debugging after seeing this. It will save you time. I’m not even going to put an example here. Watch a screencast to get started.

Use async.js to prevent callback hell

Update 2015: Promises are more powerful, but a bit harder to understand, and Functional Reactive Streams is bigger step away from imperative programming.

Before you write your callback in a callback in a callback in a callback, try out async.js. It will force you to think harder about the input and output of your functions, reduce the amount of code you write, and probably improve the testability of your code as well.

Here’s how good NOT nesting callbacks 6 levels deep can look:

async.waterfall(
  [
    // make raw Tweet into something useful
    contentTransformer.transformTweet.bind(this, tweet),

    // check the hashtags are valid
    entryChecker.hashtagMatch,

    // set the user_has_won property
    entryChecker.userHasWon,

    // save transformed Tweet to DB
    entriesController.save,

    // prepare to send a DM to the user
    twitterDirectMessager.send,
  ],
  function (err, result) {
    util.log(TAG + "saved a tweet. Err? " + err);
  }
);

Here are 5 function running in a waterfall pattern. I just have to put my functions in an array, make sure each returns the correct values, and async.waterfall takes care running them all or stopping when one returns an error, and running one last callback where I can log the result.

util.log() timestamps log messages. console.log() can log multiple objects at once

Use util.log() for messages that are going into logs. You’ll want the timestamps later to diagnose issues. Combine util.log with util.inspect() if you need to log detailed views of objects.

Use console.log() for quick and dirty checks when you forget you have node-inspector in your toolbox.

Automate running npm update after updating from version control

Hours have been wasted on this. Moving from wild files to package management is rad, but also means forming new habits. You probably won’t always notice if package.json changed in the last svn update or git pull, so why not just start running npm update by default?

Learn from boiler plate projects like MEAN and Tableau

Someone else made the hard decisions about what to name folders and files already. Tableau is a relatively lightweight example. MEAN is a stack that integrates Grunt, AngularJS, and Passport. Both packages include helpful examples.

Root users and Open File Limits

See my post on running node as a non-root user and raising open file limits to keep NodeJS web applications running smoothly and securely by using iptables and changing some Ubuntu configuration.

More things I wish I new about