My First Experience With Node.js

Attention conservation notice: these were my rough notes as I played around with Node.js probably close to a year ago at this point. I have had more experience since then, but might be useful to see how I started.

Node.js seems interesting as a backend technology because of its highly scalable nature. Also, it seems to be gaining steam in terms of developer mindshare. It is somewhat interesting to write in the same language on the front end as the backend, but then you are writing in JavaScript everywhere.

I wanted to play around with Node a bit, so I got the latest version of Node and installed by doing the standard download, unpack, ./configure, make, sudo make install. (Running on Ubuntu for kicks today.)

I thought about what things I might want to make and generally Googled around a bit. I got some ideas and a general lay of the land.

Then I said, “well there must be a Hello World app that I can play around with.” The node.js site had an example, so I copied it into a new Vim buffer. I ran it from the command line with node hello.js. There was a useful console message that was printed (as expected), and then I fired up localhost:1337 and got the expected “Hello World” message. I thought, “pretty easy!”

After getting this feedback, I took a little closer look at the code that I copied. I wondered what would happen when I commented out the res.writeHead line, and then thought it might not be visible, so wondered what would happen if I changed the Hello World line, which would more immediately tell me if my server was looking at file changes or not. I changed the string to “Hello Worlds” and refreshing the page did not change the string. Terminating the server and starting it again worked though. I thought, “this is not sustainable in the long run” and hunted for something to automatically watch for file changes.

I am familiar with guard in Ruby-land, and could have used this somehow. But I figured this was probably a solved problem and wanted to stay in Node-land. A quick search showed that using supervisor is a decent way to go (for now at least.)

NPM modules seemed interesting, so I took a look at the highest-used projects on the NPM site. These are things that will be useful going forward.

I navigated to the Node.js official documentation, and started playing around with some of the functions. I wondered if console.error would print out red to the console. I was slightly disappointed to see that it did not (although this makes sense, wouldn’t want too much color logging.) I searched around for Node console color, and found some interesting git repos, but decided not to explore this much more.

Then I was thinking, CoffeeScript would be useful. I had played around with this for Kyle and I’s Generic Space Shooter demo. I copied my current file to another one with a .coffee extension, and converted to CoffeeScript. Then I realized that supervisor probably wasn’t going to cut it. I used coffee -w to watch the file for changes, but I got an exception when I changed the file. Hunted around a bit more and found nodemon which proved to be a better solution for reloading.

Kept scrolling down the main Node documentation. Noted the section on modules and such, and figured this was a good time to try to get code in another file imported. Thought I would have made things harder by using CoffeeScript, but it turned out to not be the case. As soon as I saw the export function, I was thinking there were some things going on that the documentation didn’t adequately explain. Probably scrolling a bit more would have helped, but I saw this post and it helped to understand a couple of cases and trade-offs.

My new module just exported a function that takes a parameter and logs the parameter to the node console. However, when I tested it in the server request, I got two messages where I expected one. I searched for “node http createserver called twice” and got a helpful StackOverflow post. I ran the debug statement suggested, and it was indeed getting the favicon as well as the normal hit.

Skimmed through the rest of the official documentation, and saw a lot of things that looked like other language base constructs. Tried to focus mostly on stable features. Called it a night.

Pros so far:

  • easy to install packages
  • well documented so far
  • quick feedback cycles
  • modules are not hard to use or create

Next project ideas:

  • Chat application (seems to be the next level up of hello world)
  • Playing around with Express and seeing what other frameworks are out there for building apps
  • Integrating with Backbone and/or persistence (I have a sample project in mind for this, Backbone + Pivotal Tracker)

Meta

I kind of like this format for exploring new technologies. Basically I just create a running “stream of consciousness” of what I am thinking about and working on. It helps me remember what I am doing, where I get stuck, and prevents me from getting bogged down on small details for too long.

Night Writing With The Neo

I like writing, and I often write at night. However, writing at night on a computer monitor increases exposure to bright light and blue light, which delay sleep onset and suppresses melatonin production, respectively. Even tablets have this drawback, which is why I try to avoid reading on them at night.

Alternatives

I looked for an alternative to writing on a standard computer monitor. I considered finding a Kindle-like screen that has e-ink technology. This seemed technically feasible, but difficult to set up and maintain as well as being expensive.

I briefly considered writing by hand, but this has the disadvantages of being slow and difficult to get into electronic form.

I also took a look at some electronic typewriters (yes, really!) I could type on a familiar keyboard layout and then scan the resulting copies and use OCR on them to get the text extracted to a digital format. This seemed cumbersome and error-prone, and lacked many of the simple editing tools that a modern word-processor would use.

What I really wanted was a few line LCD display. I remembered my parents had a small address book that ran off of a few batteries, and figured maybe I would have to make something like that. In a last ditch effort, I posted to Twitter:

Kyle replied that his wife had something that might fit the bill, and she responded with some more info:

The Neo

AlphaSmart Neo

After briefly looking into it, the Alphasmart Neo seemed like it fit the bill. It has been recently discontinued, but there are enough on eBay and Amazon at the moment that you can pick up one for under $40, delivered.

Key benefits include:

  • a few lines of text that are readable in low to medium light
  • no backlight
  • insane battery life (I have typed for many hours as of the time of writing, and it still registers > 95% battery life)
  • no-frills word processor for distraction-free writing
  • syncs with my computer to get or receive files
  • eight text files open at once, with more saved to device
  • quick to turn off and on

The Display

One thing that surprised me is that the font is not always monospaced. I was thinking it would always be monospace due to the display, and I typically write in monospace. However, the display itself is a grid of pixels, not a bunch of separated characters.

The font width also depends on which specific font you select. For example, there are monospaced fonts in the system font, but the smallest font has variable width only. There is a system font that has four lines visible but with monospaced, and you can use the variant that has the same height but variable width.

Overall I like a medium font the most. The smallest font was nice for a while, since I could see the most lines of text at once. But it can be hard to see depending on the lighting. I wouldn’t want to do much text editing in this processor. Mostly just for typing first drafts or getting things out of my head. Variable width is nice to get the most characters per line. The Neo reflows text in the paragraph when writing.

Sections

I guess there is support for sections, which is helpful for navigating around the document.

Editing Quirks

There are a couple of things that I would like to change about the AlphaWord applet. First is that the keyboard repeat rate is a bit slow, so trying to hold down the keys takes a long time and then I need to flutter them instead. As a result, navigating is harder than it needs to be.

Another quirk is that there is no easy way to kill backwards multiple characters or words. Typically this would be something like Ctrl-Backspace, Alt-Backspace, or Ctrl-W, depending on the program or platform. Instead, to delete multiple words, you need to select them and then press backspace. Further, after selecting some text, I cannot delete it by starting to type. It just unselects the text and starts writing at the place that the cursor was at.

Transferring data

You can pull files off of the Neo (and put them on, although this is less useful for me at this time.) However, the encoding is a bit messed up (I think it has Windows line endings.) I made a small script to convert the encodings and rename the files into something more command-line friendly. I probably could have done the same with bash and dos2unix or some variant, but it works.

But can it run Vim?

While there are some loadable applications and presumably some way of writing them, there doesn’t seem to be a Vim application. There is a similar-looking device called the QuickPAD PRO (image comparison) that runs various custom applications and has more screen space that might be more promising for something like this. I will probably try to pick one up if the opportunity presents itself.

Recommended

Overall, I recommend getting an AlphaSmart Neo if you do much night writing or want a quality portable writing device.

Refactoring JavaScript with Grasp

I happened upon an open source tool for refactoring JavaScript that has been useful. The tool is named Grasp, and it enables searching and replacing on the AST (abstract syntax tree) of your JavaScript code. This is powerful because instead of finding or replacing bits of text throughout your codebase, you can replace only identifiers, for instance. Or you could find matching blocks of code that are spread across lines, since we look at the entire syntax tree, not the text representation of it.

There is a fantastic blog post on the Grasp website. It provides several examples of common refactorings (rename variable, changing a function to accept an arguments hash instead of adding another parameter, etc.) It really does a great job of showing why standard tools like sed and grep fall short during refactoring. The examples are clear and provide good starting points for your own refactorings.

I’d love to see a Vim plugin/wrapper for Grasp. Especially if it could do simple JavaScript refactorings (extract method/function, rename variable, to name a few.) I feel a little safer using Grasp than I do with sed, which can corrupt my git repository if I foolishly invoke it incorrectly. My typically workflow is to run a command to search for the text that I want to replace, then run it inline, and then run git diff to see any potential replacement anomalies.

The Pain Will Continue Until Understanding Improves

I was on the swim team in high school, and we would do weightlifting a few days a week in the morning. In the weight room there was a sign that read: “The beatings will continue until morale improves.” At the time I thought “this is a typical meathead thing to say. Shouldn’t stopping the beatings improve morale? I mean how is this supposed to pump me up?”

The Beatings Will Continue Until Morale Improves

While knee deep in fixing a bug that seemed like it kept popping up, I realized that the bug kept popping up because my understanding of the tools I was using was flawed. Maybe it was caching or exactly how the database is doing queries or how DNS worked. Each time, I was banging my head against the wall and until I dug in and got a better understanding of the underlying problem, I was only able to band-aid on fixes.

Typically once I have the awareness to realize that I am lacking in knowledge about a topic, the knowledge itself is relatively easy to come by. But until then all sorts of pain will arise, including unstable or flaky performance, or avoidance of the technology (“ah, who needs that! Certainly not I, guy who doesn’t fully understand it.”)

When I realize this anti-pattern, my motto is: “The pain will continue until my understanding improves.” Basically I need to stop trying to hack around the problem and fiddle with the thing that I have to try to get it to work, and instead seek a deeper understanding of the abstractions that I am using by drilling down to the details. This might be most applicable when there is not someone else to turn to for easier answers, but is a good mentality to have to grow professionally.

A lot of life is like this, actually. The things that make us uncomfortable but are unavoidable need to be reckoned with.

The Engineering Manager's Lament

There are several really good software engineering people that I know who have moved into more of a management or product ownership role. The thing that causes me to lump them in one bucket is their ability to get things done in their more advanced roles while clearly stating a desire to get their hands dirty in the low level details. I think a common thread is “man, I’d love to jump in the code with you guys, but I have this meeting.”

I think that changing roles naturally results in this feeling. When you have different or higher priorities, you must deprioritize other things.

I think these managers yearn for the simplicity of having just a technical problem to solve, now they are thrust into solving the hardest problems of the organization and doing this by coordinating resources they have never previously needed to worry much about. For managers who have been “out of the game” for longer, there may be a bit of nostalgia for the thrill of coding and having a clearly defined problem to work on. There are the war stories that drive experience but then they realize it has been ten years since they had that experience.

One reason I find this interesting is that I have a much higher esteem for people in this group as opposed to someone who does management-ish activities but does not have a technical background. I think there is a mutual respect because I know that the engineers know what is going on and can help solve tough problems that come up. They have been in the trenches and have seen some gnarly stuff. The fact that they can also manage the project is an added bonus. There is probably more empathy on both sides. I sense what it would feel like to want to jump into the gory details and not be able to. And they have been in their coworkers' shoes.

Engineering managers have one foot firmly grounded in the technical world and the project or problem domain. They know how to debug the driver issue you just ran into, and can wax philosophical about their strong opinions, weakly held.

The other foot uses those problem solving techniques and applies them at a grander scale.

Tips

So what can an engineering manager do? There are a few ways I can think of to deal with wanting to dive into the details.

The first is thinking of programming through processes. I almost envision higher level engineers of this sort “programming” by moving cards around in Trello or having a weekly meeting with the heads of four groups or having one-on-ones with their coworkers. It is not programming in the traditional sense, but more along the lines of solving important business problems with analytical thinking and processes. I think this plays to the engineering manager’s strengths while giving them more leverage.

For example, instead of coding something for four hours, they have a fifteen minute discussion with someone on their team about it. Magically, the module is coded the next day. That is 16x leverage, aligned in what is likely the right direction.

A second mentality to have is to realize that you are working on solving arguably the most important problems. While you are skilled and competent in solving small technical problems, the organization has a greater need for the work that you can do. Again, this goes back to leverage. Why influence the outcome of one module when you can influence the architecture or institute best practices that will increase the efficiency of your team? You have the ability to see the forest and the trees, and not everyone does or does yet.

Third, keep your skills sharp. Have small side projects to evaluate new and upcoming tech. Stay involved in the code by fixing one thing a week, working on tooling or deployment automation, reviewing code, and helping others with their problems. Be one step ahead of the issues that your organization will have.

You are not going to forget how to code, and you will learn other things as well. You may not remember the exact order of arguments for an obscure API, but you know how to figure it out. You certainly won’t forget what you know overnight, so relax. :)