Thoughts on Code Organization

Chris Strahorn Technical Brief

I’ve done a lot of development projects over the years and I’ve constantly experimented with different organization schemes.  I’d like to share my thoughts about them with you. Please note that the scheme that I’m currently using is not final by any means and is open to improvement and experimentation.

First, I’d like to share my goals for good code organization. A good code organization scheme should ultimately reduce the amount of time I have to think about where to put things, where to find things, and how to find related things. When it reduces time on non-coding, I can spend more time coding and fixing problems.

So, how do you reduce time not coding while still having definitive answers to location questions that are easy to figure out? I have a two-point theory on how I gather knowledge. Information that I have memorized, is intuitive, or is on my computer screen is easy to access. Information that is not in those places is much harder to access and stops the flow of work. So to keep the flow of work moving we can do a lot of things. Personally, you could try to memorize more things or get a bigger screen, but these solutions only affect your productivity instead of the entire team.  Instead we should focus on making information as intuitive as possible and making the means in which to find the information as easy as possible.

There are a couple of common structures that people use, but I didn’t feel like they were right for Mobilizer. The most common that I’m aware of is to group files by type, all javascript in a javascript folder, all css in a css folder, etc… While this scheme is perfectly fine for smaller projects, as you make more  and more features you’ll quickly have a lot of files in folders. In order to find a css file that affects the contents of an html file, you have to open up both folders and remember which one affects which. When the project is small, if you don’t remember, you can go through a process of elimination and find the right file. The cost of doing this increases for each file you add to each folder, so it doesn’t really scale.

Another hierarchy I see people follow is to group files by feature.  That is to have all the code, no matter what the file type, related to one part of the program all in one folder. This scales a lot better because you don’t have to go all over the place trying to remember where files are. The only drawback to this approach is that you have to be disciplined when making new files to follow the same scheme. You can also get into problems if there is reused code and it’s not clear where to put it.

Now that we’ve covered some common organizations, here’s the structure we use on the front-end of both Mobilizer Canvas and Mobilizer Device Lab. It’s fairly close to the feature approach, but there’s always room for improvement.

  • app (containing all of our code for our apps)
    • canvas (all the code for canvas)
    • core (all the code shared for canvas and device lab)
    • deviceLab (all the code for deviceLab)

Within a project (such as canvas or device lab) we have the following structure

  • assets
    • css
      • _app.scss (contains all of the app specific css that doesn’t fit anywhere)
      • style.scss (contains all of the app css and core css)
      • style.min.css (compiled and minified from style.css)
    • images
    • scripts
      • project.min.js (all of the css in the app minified and bundled)
  • features
    • Example Feature
      • _example-feature.scss
      • exampleFeature.html
      • exampleFeature.js
  • services
    • exampleService.js
  • project.js (contains angular module for the project)

A couple of notes about the rest of our environment. For CSS we are using SASS.  This lets us write in a super-set of CSS then compile to CSS. For our minification, bundling, compiling, etc… we are using Gruntjs.  The configuration for the grunt build is stored in a file called Gruntfile.js and a folder called grunt off the root of the project. We’re also using AngularJS as our front end framework. There are a lot of different types of Angular objects, but we’re using four main types. For the project, we have one module, which contains some global state such as external dependencies. If there’s something that we need to do in just javascript, mainly calling REST API’s and storing some global state for a set of features, we put it into a service. For all features with some UI component, we use a controller template pair if they’re used once, or a directive template pair if they are used multiple times.

There are a lot of things I like about this setup.  Because most front-end frameworks, including angular, use some sort of html templating and that template needs to be styled, it’s really nice to have all of the Javascript, CSS, and HTML in the same place. We used to only have the Javascript and HTML in the folder, and I’m really glad we switched. Now if I want to change how a component looks, I know exactly where to go.  As for the services vs. features folders, it’s really easy for me to know where I’m going because I can ask myself a simple question: does the thing I’m looking for have a HTML component?  If yes, it’s probably in features, if not it’s in services.  Assets is nice because that’s where I’d assume images and other stuff would live.

However, there are a couple of downsides to this scheme.  Assets isn’t entirely descriptive. Sure that’s where I’d think images are, but I’m not so sure I’d assume that that’s where most of the compiled stuff (CSS and JS) would go.  I think it might be better if there was a separate build folder for all of the compiled things to go.  Another downside is that there is more of a cost when adding a new feature because I have to modify the style.scss file to include my new feature’s scss file.  However, one could argue that most of the time developers aren’t creating new files, just modifying existing ones so it is a fair tradeoff in my opinion.

The way we’re organizing the Mobilizer code is by no means the best code organization ever. However, I feel like it’s a solid base on which to experiment on. I’ve tried a couple of other things on other projects, but I’m not sure if they’re ready or not. If I find anything new, I’ll write another article. Please share your thoughts on code organization in the comments below.


TRY MOBILIZER TODAY

Mobile1st is the company behind Mobilizer, the mobile optimization platform. Mobilizer helps companies increase revenue and engagement by enabling them to see exactly what their mobile users see, quickly identify display issues, monitor metrics by device, and optimize the mobile customer experience.