I love node, but I’ve run into several gotchas with node in production the last few years. Here are the top 6.
1. The website (server process) is fragile. With node, the process restarts on every unhandled exception. This is different from Ruby on Rails, where you have a separate server process like Unicorn, or PHP where it runs as an Apache module.
With one client that was transitioning from PHP to node, our first deployments felt like we were “plugging the dike” – there were so many server crashes. Until we stabilized things, this sort of gave node a bad name (the perception was that PHP was more stable – but in fact the exceptions were just hidden).
Handling all potential errors, as well as unplanned exceptions is impossible. Most deployments have another process to restart the primary node server process when it bombs. If you’re using a PAAS provider, this will be provided for you, but if you want fine grain control of your server (most web application companies will), hosting and scaling (keeping processes up and enough process around) is a challenge.
Common server-restarting libraries for node are: Upstart, Forever, or God.
2. Writing and maintaining asynchronous code. Callbacks are a simple mechanism starting out, but as your server code grows in complexity, they become a hairball. Crazy callback chains (AKA “callback hell”) make code unreadable. Even simple code that could’ve been procedural is forced to use callbacks due to the libraries you’re using.
Mixing synchronous and asynchronous code makes it difficult to handle every error. Furthermore, you have to understand the event loop to know when execution actually switches contexts. As you’re running your code – if you forget to call a callback, you’ll be left waiting to find out what happened. And, asynchronicity makes even your tests become more complicated.
The Async library exists to handle common asynchronous patterns. Personally, I prefer the “promise” (or “deferred”) pattern. It seems like a hack to send a function as a parameter, instead the promise pattern returns an object representing the state of the asynchronous call instead. jQuery has a promise library for the client side. When is the promise library we selected for a recent node-based web site (comprehensive API and more standards based).
3. Too much choice. The flip side of all those great NPM packages is that there is no clear winning web framework (think Ruby on Rails) for node – in fact, there are several competing server side frameworks (express, hapi, sails, kraken). Each with their own conventions for:
a) File structure
b) Deploying code
c) Building assets
d) Automated testing
And of course, the best choices for each of these changes monthly. This, combined with #2 is why Node is not yet a great choice for simple human facing web sites.
Thanks to Scott Nonnenberg, author of thehelp-cluster (a solution to #1) for feedback on this post.
Please leave a comment and tell me: what problems are you having with Node.js?
Most of these aren’t problems with node itself.
Haven’t used Node because I haven’t identified a situation where the benefits of non-blocking I/O are worth the overhead of learning Node. Not sure why you would use it for any other reason.
Put my eggs into the Angularjs basket and so far it’s a mixed bag. GOOD: Unit testing and E2E testing are very good, I like bower, and grunt, html directives are cool once you get the hang of them. BAD: Steep and long learning curve, could use more structure and conventions, jury is still out about whether the user experience of an SPA (Single Page App) justifies the 3 -5X dev time hit you are going to take over just doing a plain ole html app. Oh and then there is this Angularjs 2.0 ticking time bomb…
Same here. Haven’t used node in production. Only to support building client side AngularJS apps I agree with the pros/cons of angular, but embrace SPAs especially since more and more they just consume a wide range of JSON services and do a fairly good job of it.
I’ve worked out 3 broad scenarios in my head about where we are right now with regards to SPAs/Traditional app.
1) First scenario is a traditional server side app using jquery for ajax/and UI fanciness,and I have to concede that this is still the optimum choice for the vast majority of web apps considering time to market and user experience as constraints, so in this case you are sacrificing user experience for time to market. Also I think there are a wide swath of sites for which SPA is just totally unnecessary, like I don’t think Craiglist would be better if it was redone as an SPA.
2) Second scenario is SPA consuming JSON services, here you get the benefits of a more desktop or native like user experience so the decision to go this route really hinges on whether or not you need a very responsive application user experience where jQuery just wouldn’t be enough. In my particular case I’m building a web version of a native app so I decided SPA was the way to go. Is there any other reason to use an SPA besides better user experience?
3) Third scenario is hybrid client/server-side app where some parts are done as SPA and other parts are done as server side with the two different pieces redirecting to one another. I haven’t tried this yet and I’m still working it out in my head, and it means deciding when something is better off done server side and when it should be done client side. So for instance if in a part of the app, I’m just serving up static html, wouldn’t it be better to do this server side only? BTW What SPA frameworks do you like?
SPA stands for what?
Single Page Application, it refers to the type of app that passes data back and forth to a server via async calls (generally JSON), pages tend to not be refreshed but rather repainted as data or states are changed, state is managed separately on the client, and it’s this last thing that is really different from a dev point of view.
I find that SPA is a better split of concerns. Server side is basic data management with any cross user / organization logic. Since its simpler, it can be written in safer languages like golang (my new fave) or boring java. It basically just marshals json around from various data providers. The SPA can then be completely removed from data storage concerns, as it only consumes services. This lets things evolve more naturally in my experience, and makes it hard for the front end to blow up the back end (like making horrendous SQL calls that destroy the db etc). It also lets us use better distributed data stores like cassandra or partition out more traditional RDBMS in a transparent way to the client. As for frameworks, I worked mostly with Angular building my own stuff on top. I used backbone and knockout a fair amount as well. I haven’t tried any of the higher level ones like meteor etc.