Shortly after, I came across “Why I Struggle With Node” by Graham Cox. It’s a great post about why he loves Node.js, but gets frustrated with its ecosystem and prefers that of Java.
The post made me think of my conversation with my friend. I linked to Graham’s post as a starting point, added some additional thoughts and sent them to my friend to give him a place to start with Node again. After I wrote it up, I thought it might be useful to other Java developers who haven’t taken the dive into Node.js and would like to, but might be intimidated or not know where to start.
If you’re in that boat, I suggest you first read Graham’s post. It has a great list of tools to start with that translate well into front end code too.
After you read that post, here are my notes and addons that I think might be helpful if you are coming into Node development from Java in the beginning of 2017:
Also, before you dive into creating a full app or start setting up tools, learn the Promise API and use it from the start in your code. It will make your code easier to reason about, and will make your life much more pleasant once you get past the initial learning curve. If you can, use the Bluebird library for Promises. It has lots of great extras on top of the native implementation, and rumor has it that it’s even faster.
Like Graham, I use Grunt for building, too. I haven’t tried Gulp, I’m sure it’s great, but I’ve used Grunt for a while and have found it effective. Though, like Graham, I do miss the fact that Maven takes care of a lot of the gruntwork (ha ha!) for you. For my team’s apps, we have separate Grunt tasks and configurations for building front end and back end code since folder structures are different.
This is mentioned in the post but I thought I’d provide what I’ve used: Istanbul through Grunt. It’s nice and simple and does the job well.
Graham mentions that Node logging isn’t as nice as what he’s used to in Java. That’s true, but I’ve used Winston quite effectively in production apps.
Graham is right, debugging in Node is hard. I attribute some of that to it’s asynchronous nature, though.
I’ve used node-debug effectively as a debugger. It’s quite nice, but a real pain to setup. But, if I’m being honest again, usually I try to use Winston (mentioned above) to put some nice low-level logging statements in place so I can debug with those, then turn logging levels up and down as needed. Sometimes those low level statements help when you’d least expect it.
When I first started with Node, we were using a dependency injection framework in Node since my team was used to using Spring in Java. After a while, we just got frustrated with it and abandoned it.
Graham’s comments about integration testing being much easier in Java are spot on. I haven’t come across nearly as many drop in, in-memory replacements for connected systems like databases or message queues. This makes it tough to integration test. What I’ve done in the past is to create throwaway Continuous Integration database instances at the beginning of the tests and then clear them out at the end of the tests. It’s not that bad once you set it up once, but I yearn for the ease of using something like HSQL in Java.
Team Development Environments and Docker
My team has half Windows users and half Mac users. It makes for a challenging environment for everyone to setup their development environment in Node.
If you’re on a team with developers using multiple platforms, and deploy to Linux, what I recommend is to create a Dockerfile which defines your development environment. Then, use a Docker volume mount to put your source code inside the container. (Side note: Use an official Node.js Docker image as your base image). This lets you use normal Docker build/run commands to bootstrap your dev environment. The volume mount lets you dynamically update your code so you can still iterate fast, as if you were working on your local machine. It works well across platforms (no worrying about exceptions in Windows), and as a bonus, if you ever want to run your app in a Docker container, you’ve already got it more than halfway there. I’m hoping to post more about this in the future.
I’ve been developing in Node for about 3 years now, and I still really love the developer experience. Sure, I’m probably not using the latest and greatest tools that just came out, but this workflow has gotten me to a good place where I can be very productive and crank out some good quality code.
I hope some of these notes help you do the same.
What tools/techniques/libraries did I miss that were important for you when you came to Node from Java?