Front-end code organization for your complex apps

Hey! It's me!

Front-end code organization for your complex apps

Posted on March 11th 2010

Following on a previous blog post, I’d like to give you some insight on how I organize my code. Once again, I’ll be using HAML, SASS and Ruby, these are pretty much prerequisites to understanding this post, but you might still get something interesting out of my techniques.

Creating a coherent structure

Part of my job as a UX Designer is to classify “stuff”. That’s what we call Information Architecture. Sometimes it’s for an incredibly complex web app and other times it’s for your run of the mill corporate website. Those are no fun. You know what’s fun? Optimizing your development code structure! I mean, no one can say with a straight face that their single compressed css stylesheet is easy to maintain.

It might not be your case at all, but I’m sure there’s room for improvement. So how do you build your file organization? To do it, we first need to figure out and list the most basic elements of our system. Let’s see, we’ve got the main app, which has sections, which contain pages, which in turn contain sub pages, content and widgets of all sorts. It’s not much, I think we can make it work.

Concerning your views (your markup), Rails does a seriously good job at organizing them coherently. Therefore I won’t be talking about HAML views' file structure.

Stylesheets: A dire need for structure

One thing that sure needs a complete revamp is how we organize stylesheets. Throughout the many projects I’ve worked on, I’ve seen it all. Most of the time, there’s this single unmaintainable css file. Other times, it’s a completely random organization, you can see that code maintenance took a wrong turn and technical debt has accumulated. Things that made sense earlier doesn’t anymore.

There’s a much better way to go at it! Let’s consider for a minute the basic elements of a web app listed above. My approach consists of a simple hierarchy not unlike how markup is structured. Let’s dive in.

Diving in

  • application.sass — HTML elements and layout code is written here. Feel free to add in some site-wide variables. Just keep in mind, this file should only contain what is present on every page of the project. (but don’t go overboard, exceptions are ok)
  • utils.sass — is your general utilities stylesheet. Here you add some SASS magic (mixins), no actual CSS is created within this file. Let me show you mine, filled with CSS3 goodies that makes your life that much easier.
  • widget_name.sass — is where you should define those little modules that will be used a bit everywhere… I’m thinking of modals.sass and fancy_element_reused_everywhere.sass files.
  • forms.sass & tables.sass — are examples of a way of separating semantically your CSS that I like and use in most of my projects.
  • page_name.sass — this kind of stylesheet usually don’t incorporate much code since most styles are reused. Make sure you keep it specific here by either adding a unique page ID and using it as the parent element of all the styles in the stylesheet.
  • section.sass — is a figment of my imagination and an extra level of DRYness if you have sections that reuse code throughout its pages.
  • production.sass — should be the sole sass file linked in your production markup for concerns of caching, number of http requests, etc. Simply put, this file encompasses a load of sass-enhanced @import for all your stylesheets. I also strongly recommend using SASS' output style :compressed.

As your project’s integration become more complete/complex you might want to move those page_name.sass files under section_name folders.

Sometimes the application has been coded following RESTful principles and your file structure will look a lot like your app/views folder with: controller_name/new.sass, controller_name/show.sass and controller_name/index.sass. Other times the filenames will approach a more humane terminology: new_photo.sass, photo.sass and photos.sass. Whatever works for you and your mental model.

A note on UX and interfaces in general

On the one hand, it’s well known now that consistency makes a great user experience. My structure is driven by this assertion, that’s why we have a lot of high level stylesheets, it’s because we want to reuse the same patterns for the same types of data everywhere. It fits with how interfaces are best designed.

On the other hand, it’s well known that context is more important than consistency. This assertion is also supported by my structure which contains stylesheets for single pages with css rules that make them look good. Often they only have those 10-20 lines of specific code, the heavy-lifting is done by higher level stylesheets that I have duly imported at the top of the file as soon as I knew which design patterns would be used on the page (ie: tables and forms). A page_name.sass file might resemble this:

@import utils.sass /* which lets me use my utils within this stylesheet */
@import table.sass /* all the styles I need for all the tables present in this page */
@import forms.sass /* since I have a form somewhere in there */

#page_name
  /* everything page-specific goes here */

Support your web development opinions with code and structure along the same lines.

Javascript files: Not as bad, but let’s write a few lines about them

Similarly to stylesheets, these files should also be classified according to the basic elements of your project. However, there are some differences when it comes to plugins. Without further ado…

Diving in

  • application.js — contains everything relative to your whole project in terms of javascript. Think of it as the place where you extend the defaults of your plugins, initiate them and where you define a few general purpose functions and variables.
  • page_name.js — doesn’t need much explanation does it? Anything specific to the named page.
  • jquery.plugin_name.js — are either plugins you got from somewhere else on the web or some of your own created for the project. Sometimes it makes more sense to create a small plugin if you know you’re going to reuse the code and want to do so without any hassle + you can redistribute it after it’s proofed in your project (and if you have the rights to do so).
  • jquery.js — because 100% of jquery users agree: jQuery is the best.

In addition, you should clearly use some gem for javascript minimization or manually roll your own.

… and it just works!

Up to now I haven’t encountered projects that won’t work with this kind of file structure.

It’s entirely possible to develop with a single (or a few) css file(s), but would you put all your Rails models in a single file? I don’t think the only factor to creating more than a file is the length of code, it really just needs to make sense. As a matter of fact, it’s much more about the way you think of your interface that will shape your file structure.

Just what Ruby taught us.

Discussion