Skip to content

Instantly share code, notes, and snippets.

@jbruni
Created May 24, 2014 19:59
Show Gist options
  • Save jbruni/078ad838883076275a8b to your computer and use it in GitHub Desktop.
Save jbruni/078ad838883076275a8b to your computer and use it in GitHub Desktop.
About large app code structure

When I decided to move on with RequireJS + AngularJS, it was September 2013, and at that time my Google search brought many results claiming it could be not a good idea. So, I was a bit uncertain about the decision. Each day it passes since that time I am more and more pleased with the results. After refactorings and tweakings, I am very satisfied, even proud, of the resulting scheme.

My front-end code base has a bower.json specifying its third-parties dependencies - RequireJs, AngularJS, jQuery, Twitter Bootstrap (I use only the CSS from it, since I use Angular UI Bootstrap directives for the components), ZeroClipboard, every "vendor" library is specified at this very simple bower.json file.

My app code is divided into front-end "apps" and "modules"... there are two main "front-end apps" - one for logged-in subscribers, and other for logged-in administrators. Each "app" has its "modules" - in fact, view + controllers + assets. It may be hard to describe, but when you see the folder structure you do not even need any explanation.

The main cool thing I've achieved, in my opinion, is that each "module" has everything self-contained, including HTML, CSS and IMAGES. The "admin" user is known as "franchise", so picking the "franchise" app folder, you will find these files:

  • franchise.js, franchise-config.js, franchise-controller.js, franchise.css, franchise.html and a few images

and some folders:

  • settings, finance, subscribers, deliveries, and products

inside each of these folders, you can find, for example:

  • settings-controller.js, settings.html, settings.css, additional .html templates, and corresponding images

What is really exciting is to have related JS + HTML + CSS all inside the same folder: the IMAGES and CSS are related to the HTML in there, while the JS gives live and interactivity to all.

In the same level of the apps' folders, I have a "models" folder, which are services providing the data for the controllers. These "models" deal with server-side data. But none of them uses $http or $resource or Restangular or ngActiveResource. I have created my own layer to read/send data from and to the back-end. It uses $http, deals mainly with dictionary/collections/hashes instead of arrays...

Anyway: my controllers share these "model" classes, which use this custom tool/layer abstracting and centralizing AJAX requests.

By now, I have all directives and filters in a single file - they are few, so it is ok. When the time comes I will split them into their separated files.

I have lazy loading of controllers, using the "resolve" trick at the AngularJS app module's $routeProvider configuration.

So, even having a fairly complex "ecosystem", since the current structure has been formed, all can be managed with ease. At the RequireJS configuration I specify the necessary paths and shims for the third-party libraries. Then, each and every time I need to use any one of them, I just include it in the "define" dependencies list. The mentioned "models" are also "required" in the app main JS file, and injected where needed in the controllers files.

On top of it all, I am using an excellent tool called Mimosa to make a production-ready build, combining, minifying, optimizing all pieces and generating a result where the HTTP requests and the overall size are drastically reduced. All HTML template pieces got unififed in a JS templates file, which are loaded in the $templateCache at the app module's "run" function... all CSS pieces, which are connected through "@import" clauses, are inlined and minified... and Require's "r.js" optimizer, through Mimosa, merges the JS dependencies in minified builds...

I am very proud and satisfied with the achieved result... when changing a feature, EVERYTHING is at the same place: CSS, JS, IMAGES, HTML - I do not need to jump over there and there... and everything gets SMALL.... I do not have any huge file in a folder, and I do not have any folder with many files - in the contrary: if I kept old-fashioned "CSS there", "IMAGES there", and so on... either I have to reproduce the folder subdivision at each place, or I will have a huge list of unrelated files... while doing this way, dividing the folders by concern, I have a small set of files, and smaller files... specific HTML + CSS + JS + ASSETS for each "module" all in the same place; the builder will smartly combine them later... yet not in a wrap it all in a single file manner, but still following a "mini-apps" approach.

Finally, let me tell you: all this didn't come by magic or with ease. I really had hard times in the way... I had to study much more about RequireJS, r.js, Bower, Mimosa, and so on, than I would like. After the hard ordeal, I enjoy each time I find another article like this one, confirming the benefits of the choices I've made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment