Surely this is a solved problem
I’ve been programming professionally for about 6-7 years now and I’ve used my fair share of languages/frameworks/stacks. My most recent job (as well as some of my current freelance work) has led me down the AngularJS/NodeJS path. Do not get me wrong – I love using both of these in my web development work. NodeJS with Express is quite nice for writing basic APIs and AngularJS for the front end allows someone who sucks at front end work to be able to produce some pretty useful interfaces.
Now, obviously there a million-and-one things that developers debate about. For nostalgia’s sake, let’s list a few:
- Tabs vs. spaces
- Vim vs. Emacs
- Language X vs. language Y
- Whether API X is ‘RESTful’
This list goes on and on.
I try not to get sucked into these sorts of discussions, as I believe many seasoned developers in general are pretty stubborn… although I’ll admit that I have been engaged in pointless debates on more than one occasion. Admit it – you have, too!
One thing that I hardly ever hear about, though, is directory structure and file naming conventions for projects. In my experience, this has mostly been self-explanatory, or it will be documented on a per-project basis. Both of these are fine – there is something in place that makes it obvious where you should be placing your source files, and how you should be naming them.
Let’s fast forward to the beginning of my last place of employment. They weren’t really a dev shop, but they did produce software that was used internally. I was tasked to develop an internal tool that had a web front end that offered a drag-and-drop style interface to generate PL/SQL queries. I didn’t really want to use something like PHP (despite me having experience), and I had the opportunity to explore slightly more modern approaches, so I decided to run with AngularJS for the front end with a NodeJS (with Express running on top) API for the back end.
Obviously when you’re messing around with things, it doesn’t really matter where you shove files and as soon as things start getting a little bit bigger, something in your brain triggers and you start bringing some method to the madness. Your code starts to become more organised and you start organising file and directory structure.
Good one, Dave, you’ve just described every project, ever.
Hold up just a second. There’s just one thing that is bugging me. Why is doing this so damn hard for AngularJS?
The one question repeating itself in my head…
Why isn’t this a solved problem?
I have no idea.
I’m not really here to force what I believe to be an acceptable layout for an AngularJS project, but rather would prefer generating disussion on what may be better and why are things like this so difficult. Is this becoming the same sort of conundrum as coming up for effective names for variables?
The goals I want for any project structure are:
- There must be consistency in the structure
- I must be able to find what I am looking for quickly
- I must be able to find the code I am looking for based on file names and file location
- It has to scale
The first two points do happen naturally in a lot of projects. It’s the third point that seems to be where things deteriorate. The file name and location should be a very strong indication as to what is contained in the file. This sounds so obvious, but far too often I see files with either non-descriptive names, or I can’t even find a file name that looks like it might contain what I want.
Okay, let’s see where we can get
Let’s start off with something basic… Oh yeah, that is totally a hamburger .
So this one is pretty easy. We have all our JS in app.js, our AngularJS library in angular.js and our markup in index.html.
Enter problem one. As soon as the page gets any more complex than having one main view and one controller, things start to get large/hard to read. We also have the problem where we are mixing directives/controllers/services/config etc… all in the same JS file. You also have the problem of large amounts of associated markup winding in index.html.
You get it – this is going to get large, quickly.
Alright, so let’s split things out a bit.
Okay, so now we’ve got all controllers in the
controllers directory, all the services in the
services directory etc…
Enter problem two. What happens when my project has heaps of controllers/services etc… I now have directories that could have a lot of files and none of them are particularly easy to find.
Surely we can do a little bit better than this. Let’s also just make things slightly more real by adding in a bower config file, a stylesheet and also assume the user wants some URL routing.
We’re starting to see some structure – finally .
We have assets moved away from the app and we have the app files in their own area of the project.
app.js contains module declarations and run/config code and
routes.js contains our url routing config.
We still haven’t quite ticked off my third criterion that I mentioned before:
I must be able to find the code I am looking for based on file names and file location
Instead of just having directories containing all of the controllers/services/etc… for each components, how about we split things into their respective components?
We’ll also assume at this stage that the developer wants to have separate views for each controller. I’m calling them
views here, but feel free to call them
woozawozzles – whatever, as long as there is consistency.
Hey – look at that! Things aren’t looking too bad now. Let’s revisit our criteria…
There is consistency with naming. This one is pretty self-explanatory. We can find what we are looking for quickly. If I want to find the controller for the
foo component, I know exactly where that is going to live. I know that the controller logic for the
foo component is going to be in the
foo.controller.js file. It doesn’t matter how many extra components you add to the application, you aren’t going to be overwhelmed at all.
Okay, so what now?
Obviously arguments can (and probably will) be made against what I have just claimed, such as “what do we do with shared/common code?” to which I could respond with “add a
common directory in either
components/ but I think that it won’t necessarily lead to a healthy discussion.
You could also also point out that what I’ve been suggesting looks very similar to Adnan Kukic ’s article on this topic – and it is. I have read that article many times and I agree with a lot of it. However, despite Adnan presenting a very solid case, I simply don’t see his suggestions being used widely.
I really want the following:
- I want to know why there isn’t a widely accepted directory/file structure for AngularJS projects. I’m not sure “ AngularJS is new and hasn’t had time to mature ” is an answer I can swallow.
- How do we get to the stage where this is no longer a problem. I don’t really believe that every project is different enough to warrant an entirely new scheme.
Thank you for taking time to read my ramblings on this topic. For some reason it interests me more than it probably should.
I would really love to see some sort of discussion on people’s approaches on how they structure their web projects and why they think that we aren’t at a stage where there are more widely accepted approaches to this problem.