Yet Another NodeJS Experience

I have not been a huge fan of Node but I recently completed a fair-sized greenfield project and thought I’d write my experiences down.

TL;DR Node is not all that bad in some ways, still a bit scary 👻.

The Stack

The major players in the stack were express and mongoose. I had to use Node 6.8.1 so I also brought in co to yield and avoid using callbacks. In the immediate future I will upgrade and switch to async/await. I used ava and sinon for testing.

I’m not going to write about the reasons why I ended up with this stack but instead focus on what my fears were around Node and what happened with each of them.

Scary Stuff 😨

Dependencies

My biggest fear about Node was related to dependencies. It’s pretty well known and complained that Node developers lean heavily on dependencies. Not only do they make the project huge (on disk) and vulnerable to breakage when a dependency updates, but it hides what true JavaScript programming is like.

So for my project I tried choosing the oldest and most mature dependencies, and avoid language-level libraries like lodash. Before reaching production mongoose pushed a minor update that introduced a warning that the way I was connecting to mongo was going to break soon. So I fixed that and it broke my tests, so I had to submit PRs to mockgoose so my tests would pass. It seemed like like avoiding dependencies was already the right approach, and my fears here were grounded in reality.

The Language

JavaScript is pretty scary and so full of landmines that dependencies are encouraged to avoid language traps. Even with something as simple as iterating there are so many choices: for loop, for in loop, for of loop with modern Node, and forEach.

In the end, going with less libraries and trying to learn JavaScript’s ins and outs was pretty easy. Since it’s Node only one version of the language will be running the code so if it works locally in tests it should work in production. I feel like I know JavaScript better than I did before this project.

TypeScript was also tried, and it was nice to have types, but it adds a build pipeline to the backend which seems really strange so I decided to skip it. Also something about writing a language that compiles to another language which is the one that is really running is kind of scary.

The Runtime

Node has kind of a unique runtime that automatically kicks off IO concurrently and then finds other bits of the code to run in the meantime. This sounds desirable until the realization hits that most of the time in HTTP servers things happen sequentially and callbacks/Promises just create a layer of errors and confusion.

I managed to avoid most of this with co (more on that later) but I still used Promises to do a few things concurrently which went well. Occasionally I got stacktraces that didn’t reveal the true calling code, and some errors didn’t propagate in the way I thought they would. Those mostly came from dependencies that I was using that I assumed worked sanely. Another reason to avoid them!

Happy Stuff 😅

Simplicity is Possible

Since I restricted myself to a subset of the language, Node feels a lot like Go. Writing simple functions that call other functions and using parameters instead of class inheritance is pretty clean feeling and makes for easy reading code.

Also it’s really easy to use functional programming with built-in map ,reduce, and arrow functions. Using these techniques along with a good idea of how to layout the project produced a very clean and readable implementation.

Async & Await

With the introduction of procedural code style using async/await, tests and REST endpoints can now avoid almost all use of callbacks and Promises. Occasional use is still recommended when wanting concurrency, but I found Node to be almost unusable without this feature (or simulated with generators and co).

Tests and Server Start and Restart Instantly

Python, Ruby, and Go users may take this for granted but after using Grails/Spring Boot for years, this is the most amazing productivity boost ever.

The End

So with all of that considered… yes Node is pretty ok. I could see myself working in it more but I am going to try to convince all the Noders I know to go the way of TJ Holowaychuk and switch to Go.

Thanks for reading!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.