Client File Structure
Now that we have worked out how we will organize code, the next step is to determine how we will structure the source files. As inexperienced AngularJS developers, we initially decided that instead of coming up with our own file structure, we should start with examples given to us by other developers. The problem was that suitable examples were hard to come by. Most examples dealt with small snippets of code instead of looking at file structure. The only real example that we could find was the AngularJS seed project. Below is a list of how this project is structured along with what each folder is expected to hold. I have only drilled down into the “app” folder because that is the only group I propose to reorganize.
- app – Application specific files
- css – Style sheets
- img – Image files
- js – Source code
- controllers – Angular controller files. One per view (partial)
- directives – Angular directives
- filters – Angular utilities for sorting, filtering, and formatting
- services – Other Angular utility files
- app.js – The main controller for the application. Relates directly to the index.html file
- lib – Appears to be framework files (Angular files), but unclear how this differs from “Scripts”
- partials – HTML view templates
- index.html – The main view file
- config – Configuration
- logs – Log files
- scripts – External javascript, not specific to this application
- test – Unit tests
As you can see, these files are organized by file type and abstract functionality. This works well for basic projects, but for larger projects we run into a problem. Each of the folders are so general that many files will fit the description. This means that you will end up with a mountain of files in each folder which makes it difficult to find anything. Additionally, it is often difficult to organize these files into subfolders because other than abstract functionality (controllers, services, etc) these files are generally unrelated. Furthermore, because these files are generally unrelated we rarely want to work on more than one of them at the same time (no one says, “I’m going to work on Controllers today”).
After careful consideration (and several meetings) we decided that our best bet was to group the files by business concept first. After this, we can create additional file structure hierarchy if warranted. I am using our RaceTracker app as an example below:
- apps – Still application specific files
- RaceTrackerApp – If there is more than one app, add this level of Hierarchy to contain files specific to this app
- heats – code and templates specific to heats
- directives – directives related to heats in the RaceTracker application
- heatDirective1
- heatDirective2
- …etc
- HeatController.js – Generic Controller file for heats for the RaceTracker application
- HeatModel.js – Model file for heats for the RaceTracker application
- heats.tpl.html – View template (partial) for heats in the RaceTracker app
- HeatVMController – Controller file tied directly to the heats.tpl.html view
- directives – directives related to heats in the RaceTracker application
- drivers – code and templates specific to drivers
- directives – Directives related to drivers in the RaceTracker app
- DriverList – files related to the driver list view
- DriverListVMController
- driverList.tpl.html
- DriverDetails – files related to the driver details view
- DriverDetailsVMController
- driverDetails.tpl.html
- DriverModel
- DriverController
- security – code related to security specific to the RaceTracker app
- SecurityModel
- SecurityController
- assets – Non-code related files
- images – ’nuff said
- logos
- icons
- backgrounds
- …etc
- style – Style sheets
- css – compiled or unchanging css files
- less – These get compiled into css
- font – Font files
- xml – Non-configuration related files for use in the app
- …etc
- images – ’nuff said
- app.js – Main application file for this app. Should only contain code related to startup
- heats – code and templates specific to heats
- shared – If there is more than one app, files shared between them go here
- assets – Non-code related files
- directives – Generic directives
- directive1 – Folder for the first directive. Any others will be structured the same way
- directive1.html – Template for the first directive
- directive1.js – Code for the first directive
- directive1 – Folder for the first directive. Any others will be structured the same way
- security – Security related code shared between apps
- SecuritySharedModel
- SecuritySharedController
- services – Remote data calls
- services.js – All service call definitions go here. We have not found a good reason to split them out at this time
- utilities – General utility files
- utility1.js
- utility2.js
- RaceTrackerApp – If there is more than one app, add this level of Hierarchy to contain files specific to this app
- RaceTracker – This separation exists only to make the URL that the user sees smaller and less confusing
- index.html – Main application view. Relates to the app.js file in the corresponding application folder (in this case RaceTrackerApp)
- config.js – Javascript configuration for this app
- config – Configuration
- logs – Log files
- scripts – External javascript, not specific to this application
- test – Unit tests
That is kind of a lot to take in at once, but the concept is simple; Separate the files by business concept first. Developers generally work on one business concept at a time and this file structure helps facilitate this by keeping the files that they will be looking at in the same location. For example, if you are working on the Heats screen, you would not need to look very far to find the HeatModel, HeatController, heat view(heats.tpl.html), and view model (HeatVMController ) because they are all in the same folder.