Scaling JavaScript Apps – Part I: File Structure

A multi-part look at how modern JavaScript development techniques and best practices are driving the Rich Internet Applications of tomorrow. Project structure, writing specifications, build processes, automated testing, templating and applying “separation of concerns” to the world of JavaScript are all to be covered. The IDE used will be Eclipse.

File structure.

Making folders, nesting directories, arranging files.

It’s certainly not the blockbuster blog opener I had intended. Household chores elicit higher levels of adrenaline. Yet — as a method of collecting thoughts and giving each piece of work meaning — getting it right can have far greater benefits than most realise. A well designed structure can deliver you right to where you need to be in an instant, while those poorly designed will have you spending hours each week in an infernal expand-collapse nightmare of your own making.

Where do we begin?

Folders stemming from the root are usually the first port of call. They provide an immediate overview into how both the app and the development process itself are deconstructed. Obviously this will vary based on the purpose, context and individual needs of the project, but the vanilla-flavoured tree remains essentially the same. With this in mind, let’s dive into the layout of the example JavaScript project we’ll be building upon through the course of this series.

  • /lib – external libraries, such as Underscore, Backbone and jQuery
  • /src – source files and templates – more details further on
  • /specs – specifications for automagically testing your source
  • /build – all tools and scripts required to lint, test and compile your project
  • /scripts – the end game – compiled JavaScript files for production use

Whether other types of resources such as stylesheets and images deserve their own root folder, or whether they are bundled together with JavaScript in the src directory is up to you. After learning more about the build process which brings the entire show together you should have a clear idea of what approach is better tailored for your team.

Once libraries have been selected and the build process has been nailed, all of your sweet time will be spent navigating through the src and specs. This is where you should look at the app as a whole and begin drawing clearly defined lines around each component. The goal here is to conjure up a list of these modules, and sub-modules where necessary, to use when populating these directories. Aim to keep the number at any level of nesting below a comfortable maximum – if you’ve grouped more than ten folders together, try to plant them under another level of grouping. It’s always beneficial to keep in mind how you think the application will grow, so as to avoid excess file renaming and updates of path references later on.

Only leaf folder nodes will contain files, a la namespacing. You should always avoid placing files in a folder that already contains child folders – a folder should be dedicated to either grouping sub-folders, or holding the source files that make up a single building block, not both. The exception to this rule are folders that group resource types, such as JavaScript templates, stylesheets and images.

The specs folder should simply mirror the src – wherever you find a specifications file, you should be able to find the source file it tests sitting in an identical path within the source structure.

I’ll take this opportunity to give an example while shamelessly plugging tux, an open-source personal finance app I’m currently building. Beneath the source folder I’ve created a folder for each of the functions served – accounts, ledger, schedule, budget, reports, goals, and so forth. These parts are all underpinned by an additional core module and all split the templates out into a jst resource folder.

One potentially helpful feature in Eclipse when dealing with large file structures is Working Sets. Each defined set can group related resources, and when activated will display only those resources in the Project Explorer panel. This is a fantastic way of de-cluttering the explorer for when you know the work to be undertaken relates to just one or a few parts of the app.

So that’s enough of that. In the next part, we’ll take a look at writing the specifications that define each unit before any production code is written, and we’ll begin to look at how we can use a build process to neatly run these tests without leaving the editor.