March 04, 2013

AngularJS Module Seperation needs help

If you're using AngularJS as your framework of choice you probably know that it is recommended that you separate your modules according to Logic (Directives, Filters, Services) of by view type (i.e. dashboard-module) or combine the 2, but the idea is to have a single main module which depends on these "sub" modules.
This is better for testing since you don't need to load them all if you only going to test one of them, and better for keeping you stuff organized.
Currently, if you wish to create a module that, for instance, holds all the Directives, what you need to do is to have a JS file which defines the module and on top of it, it will create all the Directives with the .directive() factory method, and this is where I find the design a bit lacking, since it's really smells bad to have a big (big) file with all you're directives defined in it. no... I want each Directive to live in it's own file.
So this is where it gets uglier. If I want each Directive to be in it's own file, this means I need to load each of these files on my index.html. Now, some of you might say "Hey! use RequireJS to load them up, dummy!" but I know that RequireJS creates a whole new set of issues with the E2E tests... I really don't want RequireJS.
The direction I went with was to go with other script loaders like $script or yepnope and have them define the scripts to load on each module file - on the Directive module I will define all the directive that needs to be loaded. Doesn't work.
In the meantime, if any of you wants to share his/hers idea - I'll appreciate it :)



Keith Loy said...

Organizing modules by type (directive, service, controller, etc) is an anti-pattern and Misko actually recommends against this. I understand that this pattern is popularized by Angular Seed, which is unfortunate as it does lead to problems as you outlined. However, there is no reason to have a huge file with all of yours directives or controllers. I also use yepnope (technically Modernizr.load) in my project which is quite large and take more of the approach of Angular UI. This means I organize my modules based on a cohesive set of functionality, and not by type. I personally prefer to have a "bootstrap" file for each module which does angular.module('myModule', []) and any subsequent configuration there. I then have my main app.js file where my application module is defined. In this file I like to override any configuration to other modules in here. All in all this ends up very similar to the module structure of an app organized using RequireJS, minus the script loader.

Flashmattic said...

Hi Keith,
Thanks for commenting your thoughts here.
I know that the immediate use-case is the modules containing only Controllers or Directives, but like you I saw Misko's presentation on best practices, and from what I understood, he claims that module separation is still valid but better used for domain/view related organization, but that's not my issue - What I find annoying is the fact that I must have all the Directive, controllers, Filters etc. defined in the same file, which is overwhelming to maintain (especially if we're talking bit Enterprise applications)... you see my problem here? I don't want to hold large files where I put all the "ingredients" in. I want to separate them but still won't have to load them one by one on the main html file.