Initial Thoughts on Node.js

I’ve been building a hobby site so I can learn about non-Microsoft stacks and I spent the weekend learning Node.js. At first I was completely amazed at how awesome it was. It took about 5 minutes to spin up a webserver and start returning HTML from an endpoint! It was easy and fun! That 5 minutes of fun ended as soon as I thought “okay, now let’s write some production quality code”.

I’m not sure if it’s a problem with JavaScript or with Express, but dependency injection is far more complicated than it should be. I like to test drive my code and that means mocking out datasources so we don’t need to hit a filesystem, database, or network. That proved to be extremely difficult with Express’ `require` system. Requiring an external module basically hardwires you into that dependency, which is a no starter when you need to fake that dependency. I wasn’t able to get a constructor for the route working properly, so I ended up settling for keeping my requires in my `server.js` file and using property injection. Ugly, but it worked.

This ugly solution was bothering me, so I dug my heels in and went searching for a more idiomatic way to accomplish DI. What I found was Proxyquire. Proxyquire isn’t really DI. It works much in the same way you’d break a C `imports` dependency by creating a fake and telling the linker to use your fake instead. Only, of course, Proxyquire does this at run time instead. The documentation is good, but not great and it took about about an hour to get it working properly. It was a rather frustrating experience.

So, with a way to fake dependencies in hand, I get to writing an actual assert statement. That’s when I hit the next wall. Express’ way of sending responses doesn’t actually return anything. It all works via side effects. So now I could go install Sinon and learn a 4th library or I could just not write the tests because I’m not having fun anymore. Wasn’t that why I fell in love for that brief moment? Didn’t I love Node a few hours ago because it was easy and fun?

That doesn’t mean that I don’t have a use for Node.js though. I would absolutely use it to quickly prototype an idea. It’s completely fantastic for getting something simple up and running quickly. However, I would then just as quickly throw that prototype in the trash and write my production code in something else. A platform being quick, fun, and easy doesn’t matter if it’s hard to do things the right way. If it’s easier to write tightly coupled and untested code, we will. I don’t know about you, but I like knowing my code works and will continue to work.

Before I tried Node.js, all I could think was why would anyone want to use JavaScript for their backend. After a few days of learning it, I’ve found a use case, but am still left with a sour taste in my mouth. Maybe I’d be less disappointed if I hadn’t had a moment early on where I fell in love with it. Granted, there’s no way I learned the idiomatic way to write a Node web app in a few days, but I just can’t see myself ever using this for a production application. If you know of any good alternatives to Express that make testing Node code easy, please let me know in the comments. I hate to write off such a fantastic platform prematurely.

Advertisements

,

  1. #1 by Dan Pantry on November 14, 2016 - 12:53 pm

    You seem to have fundamentally misunderstood the module system. `require` is *not* part of express; it’s part of the CommonJS module syntax, which is employed by Node. It’s not a replacement for dependency injection frameworks like intravenous. The reason proxyquire ‘feels’ dirty is because it is a dirty hack 😛

    You can achieve DI by structuring your code correctly, like you would do in Java or C#, rather than trying to break modules. You don’t break namespaces in those languages, do you? 😛

    Like

    • #2 by Christopher J. McClellan on November 14, 2016 - 1:00 pm

      I have literally zero doubt that I’m not understanding something, and that’s the root of the sour taste in my mouth, but I’m going to stand by what I said about it needing to be easy. Also, you don’t really want to get me started on the idea that you need an IoC container to do dependency injection. An IoC just shouldn’t be necessary.

      Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: