Blog posts from June 2009...

When JavaScript Attacks, errrr, Hacks

I've been doing a lot of JavaScript coding in my recent work on Launchpad. I mean, a lot! We're pushing to get every aspect of a bug page editable within the page itself, hopefully making it easier to manage bugs without being directed to another web page. Everyone on the Launchpad bugs team is working on some part of this. I haven't previously done any JavaScript coding like this, and now I'm sitting with a 1400 line JavaScript file that has grown unwieldy and needs to be tamed. I'm starting on that refactor this morning and thinking on the things I've learned as this file has grown seemingly with a mind of its own.

I should note some of the conditions that led to this. I wrote that I haven't done JavaScript like this before, but it's not as if I lack experience with js. I've done a lot of JavaScript coding both in previous jobs and for fun, everything from minor usability improvments to extensive page functionality in JavaScript. I've taught conference tutorials on AJAX and was even working on a book on Google's use of JavaScript in it's apps. (Yes, I'm a failed tech book author at this point, but the point is still valid, I think.) But all the work I've done previously either started in JavaScript and added server components as needed, or started with the server-side and added JavaScript in targeted areas. This work we're doing on Launchpad bugs has an existing, sophisticated server component -- the bug tracker -- and now needs an extensive JavaScript application built on top of that. Adding complexity is that the JavaScript component is being built piece-by-piece in small branches, rather than with a cohesive architecture. And by several developers at once.

It's this part about building an extensive JavaScript application in pieces that is really the new part for me, and I've learned some things I'll carry foward in terms of how to build a nice JavaScript module in small bites.

Global Module vars

Sticking variables into the global namespace of a module (so multiple functions have access to the variables) is now my sure sign that I need to refactor. From here on, I'll create an object rather than doing this.

This seems obvious but we're using YUI3 where each module is akin to an object itself, so it wasn't that clear to me. I would avoid module-level globals, even inside the module pattern itself, and create distinct objects the moment I begin to need state across objects or functions.

Closures

Again, YUI's module pattern and the way our Launchpad API is designed encourage callbacks via anonymous function closures, especially when dealing with XMLHttpRequest. And really this is a fine thing, and a common pattern when doing async js coding. But it's easy to let the closures get out of hand, which makes the code harder to read and maintain and makes debugging a bit harder, too. So I'm trying to use closures only as I have to.

Custom Events

Given the previous point, I think it's good to fire custom events to signal when to do some work. A custom event when an XHR has completed, or a custom event when it's time to update the DOM. A custom event when some state is initialized, and so on. Custom events are my new mantra going forward.

Perhaps I'll look back after this refactor and feel I've abused this pattern as well, but I think it will be cleaner and will be easier to test.

Patterns for Reuse

And finally, the next time I get into some extended bit of JavaScript work, I'm going to think about the patterns I'll be using and about the overall architecture earlier. Even though I'm sure I'll still be doing small branches that add small bits of functionality, I'll try to look ahead more to where this code might be reused across Launchpad, where this pattern of functionality or interaction might be repeated, and where the code I'm working in is likely to go over the next two cycles.

Link | Posted by deryck on June 26, 2009 | 0 comments

The Early Morning Internets

Most everyone I work with knows this, but friends and family may not -- so just in case you haven't heard -- my work schedule (which means the time I am available online) has changed since I joined Canonical. I am now up very early to better match European time zones, where the other members of the Launchpad bugs team are located. How early, you ask?

I wake at 4:30 am, and I'm at work by 5:00.

A pause while that sinks in on all my musician friends.

Work hours are now 5:00am-2:00pm, but in practice I knock off closer to 2:30 or 3:00. I try to avoid being online after that. I usually spend the afternoons playing with kids, cleaning the house or yard, or other such family/home activities. I usually come back in the evenings for an hour or two of work before I go to bed, but I rarely jump on IM or IRC in the evenings -- evenings are for quite work. Note the usually in the previous sentence. This is not a work requirement -- have I mentioned Canonical really is the best employer! -- and in the summer I'm finding it harder to find time in the evenings with the kids out of school and staying up later. Usually, the girls collapse by 7:00-7:30 on school nights, so I enjoy coming back to the laptop for an hour or two to unwind. Sometimes this is work-related, and sometimes it's just for fun hacking (which may even be work-related still, believe it or not!)

So all of this is to say, if you want to or need to catch me online via IM or IRC, make it happen from 5:00am-2:00pm CST. For you west-coasters I may never see you online again, so ping me out a day early if I need to stay around to catch up with you. :)

While the schedule is different for me in terms of my time online, it really is the perfect schedule for me. I'm focused early, getting a lot of work done, and enjoying working on Launchpad a whole lot. And then there's still time in the day for doing the things a husband and father likes to do.

Link | Posted by deryck on June 24, 2009 | 0 comments