

Code Organization in Large AngularJS and JavaScript Applications - joelhooks
http://cliffmeyers.com/blog/2013/4/21/code-organization-angularjs-javascript

======
SoftwareMaven
I was surprised at Angular-seed's directory structure. It is fine for toy
apps, but that isn't what it is really being billed as.

I'm building a django/angular app. Each django app gets its own angular
module, and each angular module roughly shares the seed structure, but may be
broken into more files (much like the second example in TFA). So my whole
structure looks something like:

    
    
      django-project/
        app1/
          views.py
          static/
            coffeescript/
              app1.coffee #defines the module
              app1/
                directives.coffee
                controllers/
                  foobaz_controller.coffee
            ...
    

The only thing I'm not keen on is the duplication of "app1" in the directory
structure. It is done to prevent conflicts when static files are collected,
but is redundant during development.

Thinking through this, I might be able to build a static files finder that
looks for an angular directory in the django app and puts it in the right
place. I'll have to think about that, since there are a lot of moving pieces
with pipeline, et al, involved in the chain.

~~~
davecap1
I recently completed my struggle with AngularJS/Django and the asset pipeline.
I was using django-compressor but that was really not pleasant. What I did was
completely decouple my AngularJS app from my Django app. I stopped using
Django's collectstatic as well, and now use Grunt to compile my assets into a
temporary "static" directory (not stored in version control), from an "assets"
directory (stored in version control). I then use a fabric task to upload the
contents of "static" to S3, to new directory with an incremented build number
(something like s3://my-bucket/dist/v1234/). Once that is done, I update
STATIC_URL in my Django app to reflect the new dist path.

My one tip: forget about using Django to manage your assets if you need cache-
busting... use fabric and something like grunt.

------
TikiTDO
This has always been a pet peeve of mine with projects like rails. Usually
when I work on a piece of the system I'll be working on a single component, be
it user, product, report or whatever. That means I will either have a bunch of
different directory trees open in my IDE (Which can be bigger than a screen
for large projects), or I will be using some quick-open tool (Which still is
great when you know what you want, but less so when you just want to get a
quick overview of a component).

God forbid I try to edit multiple components at a time, and forget browsing my
repo on github. Organization like this would make life so much easier in so
many ways.

------
davecap1
A nice example of a slightly larger AngularJS app can be seen here:
<https://github.com/angular-app/angular-app>

~~~
aidos
Say, that _is_ a good example!

I find the general layout suggested for Angular apps to be a bit weird. There
are prominent articles by Angular devs that suggest splitting things into
services, models etc. I guess it just follows the familiar pattern that Rails
etc give you.

I've recently built a couple of large(ish) python web apps. I use Flask for
the web frontend but instead of starting with Flask I built all the libraries
/ core code first and then use Flask to tap into that. It makes for a much
better application structure. Instead of thinking about how you should be
splitting into blueprints you really think about the application structure as
a whole (and you remove dependencies on the framework). I'm _much_ happier
with the results.

I'm refactoring the Angular frontend at the moment so the example you've
pointed to is a timely piece of code for me to skim. Thanks!

------
drinchev
That's just the tip of the iceberg. Many complicated projects have landing
page which should not include the whole javascript app, but still need the
same collections & models. Or for example website with CMS will include
administration part which is fairly different in structure.

My applications are backbone based and my directory structure is similar to :

    
    
       scripts/
         classes/
           collections/
             socket.coffee
           ui/
             popup.coffee
           page.coffee
         models/
           user.coffee
         collections/
           items.coffee
           products.coffee
         ui/
           navigation/
             top.coffee
             sidebar.coffee
           overlay.coffee
         pages/
           landing/
             home.coffee
             about.coffee
           cms/
             home.coffee
             admin.coffee
         utils/
           templates.coffee
         landing.coffee
         cms.coffe
    

What's important in my app is classes path. I put there only reusable classes,
and using coffeescript I can simply extend the whole module by

    
    
       class Items extend require('classes/collections/socket.coffee')
    
       module.exports = new Items()
    

Also I always use utils folder, for general javascript helper functions.

------
Kiro
What's in these files?

    
    
      models/
        CartModel.js
        ProductModel.js
        SearchResultsModel.js
        UserModel.js
    

I have a lot of controllers, directives, filters and services which sit fine
in their own files/modules but I don't understand what I would put in a model
file.

~~~
olouv
Model files in angularJS are often basic wrappers around either $ressource or
$http. From that you can add default values, collection-like functions, etc.

~~~
joshuacc
Do you happen to have a link to an example for those of us just getting
started in Angular?

~~~
psgibbs
I think typically people start them out in 'services.js' since effectively
models in angular are constructors that are created, and then injected
whenever you need a certain type (so you have a service that returns the
constructor function).

A good example of this is how the tutorial treats the restful 'Phone'
resource, creating a service that injects the resource where necessary. I've
started calling them 'models' rather than 'services' internally as well, so
it's interesting to me that others are too.

<http://docs.angularjs.org/tutorial/step_11>

------
tinco
I'm building a rails+angular app at the moment, and sort of fell by default in
the component-type folders. Reading this blog makes me think that you're right
and topical folders are much better, but then an alarm bell goes off. If this
is a good way of doing it, why isn't it the Rails way of doing it?

Does anyone know if the Rails core team ever discussed using this directory
layout? I know that it would take a fairly big rewrite of some glue logic in
Rails that we all know and love, but merely 'hard to do' often does not stand
in the way of 'the right way' in Rails.. right?

Can anyone point out something that immediately stands out as possibly
problematic?

~~~
stackus
I thought the same thing.

In my minds eye I don't see a nice place to stuff views. Module specific ones
could live inside the module but Rails has layouts and also typically has
shared views.

Sinatra would be a good framework to play around with this structure.

------
jared314
This reminds me of the beginning of Bob Martin's keynote[0] at Ruby Midwest
2011[1]. I don't agree with everything he said, but the code organization
point is sound.

[0]
[http://www.youtube.com/watch?v=WpkDN78P884&t=6m39s](http://www.youtube.com/watch?v=WpkDN78P884&t=6m39s)

[1] <http://www.confreaks.com/events/rubymidwest2011>

------
liberte9
I'm not sure I agree with the idea of adding utility methods to the $rootScope
to avoid wiring in dependencies repeatedly. I would probably go with defining
a utility class and indeed injecting it into every controller that needs it. I
like the idea of having my utility methods clearly defined in one place. Any
opinions here on the pros/cons?

~~~
camus
I'm for using services to define whatever object used across controllers and
other services. Using rootscope or scope inheritance is very tricky in
AngularJS

~~~
ganarajpr
Agreed. Any utility functions should go into a different service.

Using $rootScope feels like a hack.

------
brianfryer
Much thanks for the write up! I'm currently pitting together my first Angular
app and feel much more confident in a design decisions that I've made so far.

------
iaskwhy
Body text is really light making it hard to read, at least on my eyes. The
content seems interesting though.

~~~
cliffmeyers
Thanks for the feedback. I made the text darker.

~~~
afandian
If you're in the mood for constructive feedback, there's something that makes
that page difficult to read. It could just be font rendering at that tiny
size, it could be the contrast with the line spacing given the text size.
Either way, taking the font-size up to 15px makes it readable, for me.

