This blog-post is perhaps misnamed. What I want to convey in this blog how you have to change the way you work when you go from a strongly typed language to one of the dynamic languages.
I pride myself on being language agnostic. I know that I have software running in some deployed and used system in more than 30 different languages. In general, I don't care if I'm programming in Java, Scala, Pascal, C++, Python, Eiffel, Smalltalk, Self, or any language you care to mention (although, I have to admit that some of the languages I've used are less effective than others).
What I found sooooooo… frustrating!
Here are the sources for my frustration:
- Where is my autocompletion?
I'm in Eclipse, I'm programming using some library that I've hardly used. I know the method on this object ought be be something like 'searchXXX'. What do I do? I simply press %-Space and Eclipse show me all the options. These are not guesses, Eclipse has inferred the type, parsed the target type and knows what the options are. I can't go wrong!
- What??? No classes???
- Where do my files go and what conventions to use?
Most Java frameworks define very clear rules for where you place the code, what your options are, etc. You know that the namespaces match the directory structure, the classes are placed in files with the same name, etc. Also (and this is more of a Node.js issue), if you're building a web-site, you know how to find artifacts. You'll perhaps start with the WEB-INF directory, look at the web.xml file, figure out what URL's goes to which servlets, etc. If you've seen one application, you've seen them all (almost).
When you work in Node, there are no such 'standards'. There are multiple options for anything. There are many competing frameworks and even if you run across two projects that are based on the same framework, the two projects may have organized the code in two completely incompatible ways.
As I was learning Node, I though… it makes sense to be test driven with dynamic languages, but before i learn any unit-testing framework, let me first learn node… This is simply the wrong way around! The first thing to do is to learn one of the unit testing frameworks. I went through a few of them and I can highly recommend the mocha framework.
The installation of the mocha framework is simple:
$ npm install -g mocha
This gives makes the mocha command available to you.
In every project you create from then on, create a test directory, create a directory called test and before you do anything, write your unit tests.
Next, run mocha process that watches the changes to files in the directory and executes the tests automatically on every change. This command looks like this:
$ mocha -w -R min
If I change a file, I'll immediately know if I broke something.
Study not only experiment
If I pick up some library online in Java, my typical work pattern is as follows:
- I'll download the library (say by adding it to some maven pom file)
- I take a look at the documentation (typically read through the Quick Start to get an idea of how I'd like to use the library
- I explore the library by looking at the API
- I start programming. In most cases, I'll be OK as the autocompletion available in my IDE will help me get the spelling correct and show me my options.
When you move to Node, you just can't work this way! You have to take the time to study the library. You may of course experiment as well, but I suggest you do this in a sandbox far away from your production code. Only when you have built up some degree of proficiency can you start using the library.
I kept making this mistake in the beginning. I was following my usual routine, however, without autocompletion and the ability to command-click into the source (or ctr-click on windows), you'll be wasting your time.
Here is my new routine:
- Set aside some reasonable amount of time.
I typically set aside 1-4 hours to learn a new library.
- Make sure you picked a library that is wide-spread.
I can't tell you how many times I found a JS/Node library that looked promising in its description. Started to use it then to discover that it has serious flaws and that there is a single contributor and had to back out. Spend some time researching how many others are using it, what are the alternatives, etc. The JS library market is in its infancy. There seems to be more libraries than there are programmers. I fully expect this chaos to subside (I don't know if you where around when we had the same problem in Java, but it quickly resolved itself through a darwinistic process).
- Skim through the documentation from A to Z.
You don't have to read every word, but build a picture of what ALL the features can do for you and ensure that it is a good match for your problem. Developers aren't always the best writers and reading through the documentation can be painful, but if you focus on skimming it's not too bad. I usually follow this up with a quick mind map (there are plenty of mind-mapping tools out there if you don't like pen and paper). This often exposes gaps in my understanding and I have to go back and reread some section.
- Create a sandbox project and start with their tutorial.
Most library have some kind of quick-start, or perhaps a sample application that you can run. I usually also go to GitHub and see if I can find some projects using the library.
- Create a throwaway application solving what you want to solve with the library.
Create another sandbox project and make a simplified implementation of what you're trying to solve (the reason you wanted to use the library in the first place)
- Produce some documentation/notes explaining the library in your context.
Finally, I usually write up a summary of the key features and the API's of the library (showing age here… I do this so I can remember).
Often I bail from the library in step 2 saving myself a lot of time.
Understand and accept the node philosophy
I often hear developers complain about various programming paradigms. Sometimes, this is because they haven't bought into (or simply not gotten used to) the style or philosophy of a new environment.
When moving from Java to Node, there are a few things that you have to learn to accept. In particular, node seem to shy away from transitional object-oriented frameworks (the kinds that are built on the Hollywood principle: "Don't call us, we'll call you").
As an example, in Java if you built web applications, you would know where to find the source code,, where to place your files, how to configure filters, etc. JEE defines this, your web server implementation will follow the rules of the JEE specification and you as a programmer would simply 'plug in code where specified'.
Not so in Node, in Node you have the ultimate freedom (freedom coming with a tremendous amount of responsibility). There are no Tomcat, no JBoss etc. You're on your own. In fact, I hear people compare Node to JEE (or Play, Django, PHP, …) which is actually a bad comparison. Node is just a Java Script interpreter. Node doesn't understand the web. To get Node to do something with parity to the frameworks it is being compared to, you'll have to add libraries. Your program will have to configure these libraries and now you have parity (or perhaps more than parity).
So if you want to compare Java artifacts to Node artifacts, it'll look more like this:
- JVM --> Node
- JEE Web Server --> Tons of libraries, perhaps the most popular being Express.js, but there are many alternatives
The node approach has advantages and disadvantages. In the beginning, I found the lack of consistency between various applications (developers are free to configure their file structure as they please) to be a mistake. I was trying to learn by looking at various projects using some of the most popular libraries, however, it seemed every developer had their own idea of how to organize their code making it very difficult to learn.
However, later, I had some unique requirements where I had to combine technologies that would have been really hard to do in Java. In Node, this was easy because I have full control.
You may not like this philosophy, but if you want to be efficient in Node, you'll have to understand it and accept it.
The transition from Java to Node (or more generically from strongly typed/standard rich environment to a loosely typed/few standard) can be frustrating. If you are to be successful in this transition, you'll may have to change the way you work. I recommend using TDD, to spend more time study the various libraries you encounter and embrace the philosophy.
I started out being very uncomfortable and inefficient when building Node applications. By changing my routine, I think I've managed parity in terms of productivity of that I experience in more rigid environments (e.g. Java)..