How to organize and structure the files and folders?

Coordinator
Jul 11, 2012 at 9:25 PM

An important question is how should we organize the source into files and folders.

The primary goal of any organization scheme should be to make source easy for a developer to find the code they are looking for.

In addition, the organization should promote good practices such as Separation of Concerns.

To this end, we have favored:

  • A file should contain a single "module". We need to explore further what we mean by "module".
  • The folder structure should reflects the "namespace" of the module. For example, a module exposed as MyApp.storage.search should be located at \MyApp\storage.search.js
  • "Namespaces" should reflect features/functionality and not architectural layers. For example, we favor having all the files for a particular feature (e.g., cropping an image) grouped together rather than having all the JavaScript files grouped together. (Consider the folder structure in a typical ASP.NET MVC or Ruby on Rails app as a negative example.)

We have also been influenced by the Asynchronous Module Definition spec.

How do you feel about this approach?

Additionally, at least one awkwardness of following this strictly is that we could end up with a folder full of similarly named files. Compare the following path in these two commits:

/Hilo/pages/

The current code follows the rule strictly, but there is more noise when navigating the source.

Jul 11, 2012 at 10:13 PM

Overall I like it. It's definitely better to group assets by feature, and not by file type/layer. I think having a folder per page is a good approach. It makes it easy to relate the running application back to the source. As application grows over time, the folder per page structure will scale well. You could even introduce sub-folders for pages that have lots of separate components.

We should also consider where shared assets and 3rd party libraries go. You could add another folder /Hilo/shared that contains assets used in more than one page.

Jul 11, 2012 at 11:54 PM

+1 to all of this.

i'm also a fan of folder per page. i started doing that in my own sample apps today and i really like the way it turned out.

it's also important, at a high level, to group things in to folders based on the high level functional area of the system. if there are 2 or 3 pages that comprise the cropping feature, for example, there should be a high level /cropping/ folder that contains all of these. this will make folder-per-page more manageable in the long run.

like everything we do, though, this should be guidelines and heuristics, not absolute rules. exceptions will be made, and they should be noted in comments or other places that make the exception reason known, easily.

Coordinator
Jul 12, 2012 at 12:15 AM

@derickbaily with respect to

"if there are 2 or 3 pages that comprise the cropping feature, for example, there should be a high level /cropping/ folder that contains all of these"

Would you also expect each file to correspond to a "module"? (See this discussion.) Likewise, with namepaces. Suppose we have this folder structure:

\Hilo
..\cropping
  .. \viewmodel.js
  .. \appbar.js (<- perhaps this is bad example, but bear with me)
Would you expect namespaced objects such as Hilo.cropping.viewmodel and Hilo.cropping.appbar?

Jul 12, 2012 at 12:35 AM

in that simple scenario, yes. it makes sense to me to see the files namespaced in the folder (think C#)

now let's say there are multiple modules within cropping... perhaps there is a wizard for cropping. 1 page to set the cropping size and one page to review the changes before saving. in that kind of situation i'd do something like

 

\Hilo
  \cropping
    -viewmodel.js
    -appbar.js
    \crop
      -crop.html
      -crop.css
      -crop.js
    \confirm
      -confirm.html
      -confirm.css
      -confirm.js

I would consider all of this to be the "cropping" module, or functional area of the application.

unfortunately, "module" has too many meanings so this is where that other conversation will come in to play :)

Jul 12, 2012 at 11:56 AM

I'm generally aligned with the approach of separating the files by function rather than type. But I wouldn't want to take this too far. The previous example shows folder-subfolder.  I'm not sure we need the subfolder approach and I definitely wouldn't go folder-subfolder-subfolder. When you have to support or manage someone elses code, lots of little directories to go through can be tedious.

Jul 12, 2012 at 1:28 PM

like everything else we do, there's should not be a hard and fast rule on any of this. the worst thing we could do is make a single decision and then set that in stone, always to be followed. we need general guidelines to start with, and we'll discover the best way to keep things organized as we move forward. as that happens, we'll figure out when and why it makes sens to keep things flat vs make things deep

Coordinator
Jul 12, 2012 at 11:51 PM
Edited Jul 12, 2012 at 11:53 PM

<opinion>Rules are derived from Principles. If the misapplication of a rule violates the guiding principle, you should not apply the rule. Go back to the principle instead.</opinion>

The principle here is "to make source easy for a developer to find the code they are looking for".

Also, I just added one level of subfolders. ;-)

Let me know what you think.

http://hilojs.codeplex.com/SourceControl/changeset/changes/091a593ece50

Jul 16, 2012 at 2:28 PM

+1 to "rules are derived from principles"

How pedantic do we want to get here? :)

The principle goes deeper than source code organization. It has more to do with cognitive psychology, how we organize and understand information, and creating logical groupings to facilitate that grouping. We generally have a 5 to 7 item-grouping heuristic in our brains. It varies a little from person to person, but there are dozens of studies in psychology, and in software usability, that say we see small groups of items as having a relationship to each other. That is, when we see a maximum of 5 to 7 items in close proximity, we see a relationship between them simply by having them grouped together. When we provide a name to this group, we create context for the relationship and create even more meaning.

A more meaningful context can also be created when we organize items by higher level function and use - a group that facilitates something the individual pieces don't facilitate on their own. That is, if we create groupings of place settings for a table - spoon, fork, knife, plate, bowl - we see the larger function of the place setting to sit down and eat. In comparison, grouping all of the spoons together, all of the forks together, etc, only shows us a collection of the same items and not a higher level functional grouping with more meaning. 

So the principle could be the organization of information in to logical groupings, based on proximity to each other, and based on a functional relationship to each other. The rule, then, would be to create sub-folders to signify the relationship between files and/or other groups of files, in order to facilitate the understanding of how the application is laid out, how functionality relates between each portion of the application, and there-by create a more logical file system layout that is easier for someone to make assumptions about when looking for the files that they need.

Jul 16, 2012 at 3:30 PM

regarding the folder changes you made: i would drop the "pages" folder. it's an unnecessary grouping by type of file. it would be easy enough to see the organization without that parent folder, and provide more flexibility in how we approach the code within the "crop", "detail", and other folders. 

For example, with the current parent "pages" folder, we might end up with an "entities" folder to contain model and collection definitions. This may end up reproducing the same sub-folder structure of "crop" and "detail" if we go down the view-model or presentation-model paths. At that point we would have this:

\Hilo
  \pages
    \crop
    \detail
  \entities
    \crop
    \detail

This is organization by type, not by relationship of functionality. It would be better, in my opinion, to invert this structure:

\Hilo
  \crop
    - entities.js
    - crop.js
    - crop.css
    - crop.html

If we end up in a situation with multiple pages in a functional area, then sub-folders would make sense within the functional area:

\Hilo
  \crop
    - entities.js
    \somepage
      - somepage.html
      - somepage.css
      - somepage.js
    \anotherpage
      - anotherpage.html
      - anotherpage.css
      - anotherpage.js

where the "entities" is a shared file between the two pages

Coordinator
Jul 16, 2012 at 8:02 PM

I'm okay removing the \pages\ folder.

Jul 26, 2012 at 3:39 PM

Yes, I don't think pages folder adds much. I'm also not too crazy about the somepage and anotherpage folders. I wouldn't expect a huge number of page files under what is already a functional breakout, so these look less than useful to me. I would think the need to have this would be the exception rather then the norm.

Coordinator
Aug 7, 2012 at 5:16 PM

Take a look at the latest code (hub in particular) and let us know what you think. Feel free to raise this at the advisory meeting this week.