Friday, August 8, 2014

Node.js API - How to RTFM

So, you've decided to RTFM? That's great, but there's a reason no one's doing it. Does this sound familiar?

You start reading and you run across a reference you don't get. So, you add a mental sticky note to mark your place and jump off to learn what an EventEmitter is. While your reading, you run across util.inspect. You're not sure what that is, so you add another placeholder and jump over to learn about it. While you're trying to understand the util module, you realize you're not exactly sure how module loading really works. You jump over to the modules section. Eventually, you forget why the hell you wanted to learn Node and start watching Futurama.

That's pretty common in my experience. It's a shame, because the documentation is pretty thorough, there's just not any direction. It's akin to studying English by reading the dictionary. Ignoring the question of if this is a good way to learn Node or not, wouldn't it be cool if it were an option?

Well, there's a pretty straightforward solution.

I went through the entire API and noted the external references mentioned in each section. After this exercise, I understood why I kept getting lost. Here's a diagram of each module and its dependent modules (those that you need to understand first).

I thought this would be a good study guide, but it was intimidating. Since I'm lazy, I took my list of modules and their dependencies and transormed them to json. Then, I wrote a script to embellish the dependencies a bit, by recursively including their dependencies. The results were then de-duplicated and with a little more parsing, I was able to see each module and those that should come before and after.

{
  name: 'process',
  before: ['console', 'events', 'module', 'stream', 'util'],
  after: ['child_process', 'cluster', 'crypto', 'domain', 'fs', 'global', 'http', 'https', 'net', 'readline', 'repl', 'tls_(ssl)', 'tty', 'zlib']
},
{
  name: 'fs',
  before: ['console', 'events', 'module', 'process', 'stream', 'util'],
  after: ['crypto', 'domain', 'https', 'tls_(ssl)', 'zlib']
},
{
  name: 'child_process',
  before: ['console', 'events', 'module', 'process', 'stream', 'util'],
  after: ['cluster', 'domain', 'http', 'https', 'net', 'readline', 'repl', 'tls_(ssl)', 'tty', 'zlib']
},

So, this worked pretty well. It shows all the modules and in which order I should read them so that I'd understand any references I ran across. To make it even simpler, below is the list I used while navigating the Node API docs. I'm happy to say, I've now gone through all of it (except a few that I could see were not essential at this time) and understood it. Hopefully, this list will help you if you decide to do the same thing.

Cheatsheet

*Note: I just listed the count of dependent modules so I could see if it I'd limit myself by skipping one.

  1. module (after: 28)
  2. querystring (after: 0)
  3. assert (after: 0)
  4. console (after: 26)
  5. os (after: 1)
  6. url (after: 5)
  7. path (after: 0)
  8. dns (after: 0)
  9. debugger (after: 0)
  10. timers (after: 2)
  11. buffer (after: 2)
  12. addons (after: 0) Wait until you're bored with Node and want to write C++ to do this one.
  13. util (after: 19)
  14. punycode (after: 0) Wait until you need it to learn this one.
  15. stringdecoder (after: 0)
  16. events (after: 17)
  17. vm (after: 0)
  18. stream (after: 15) Just do the first part. The API for Stream Implementors can wait until you need to write your own.
  19. dgram (after: 0) Nothing depends on this, so wait until you need it.
  20. process (after: 14)
  21. fs (after: 5)
  22. child_process (after: 10)
  23. global (after: 0)
  24. net (after: 9)
  25. crypto (after: 0)
  26. repl (after: 0)
  27. tty (after: 1)
  28. readline (after: 0)
  29. tls_(ssl) (after: 1)
  30. http (after: 4)
  31. cluster (after: 0)
  32. zlib (after: 0)
  33. https (after: 0)
  34. domain (after: 0)