Marty Pitt Marty Pitt - 1 year ago 90
AngularJS Question

AngularJS : File concatenation breaks module declaration order

I'm using grunt to concatenate my

files for my Angular app.

I've just gone through and tidied up the codebase to follow the conventions discussed here, specifically, grouping my code into small modules that represent features.

However, I'm finding that the order of concatenation appears to break the app, if a module is consumed before it is declared.


|-- src/
| |-- app/
| | |-- userProfile/
| | | | userProfile.js
| | | |-- deposits/
| | | | |-- depositFormCtrl.js


// userProfile.js
var userProfile = angular.module('userProfile',[])

// depositFormCtrl.js
.controller('DepositFormCtrl', function($scope) {...});

When grunt performs the concatenation,
appears before
. This causes the app to throw an error, complaining:

Uncaught Error: No module: userProfile

I see lots of talk about the possibilities of using RequireJS / AMD to manage the load order of the modules. However, often it's stated that this is overkill / not required, as Angular handles this for you.

E.g: Brian Ford of the Angular team mentioned:

My personal take is that RequireJS does too much; the only feature that AngularJS's DI system is really missing is the async loading.

He's also stated elsewhere that he doesn't recommend RequireJS with Angular.

I've also seen mentioned made to using angular-loader.js, as shown on the seed project. However, as I understand it, (there's little official documentation) the loader aims to solve the problem of loading modules out of order, rather than them being referenced before used.

Adding angular-loader.js to my project didn't resolve the issue.

Is there a declaration I should be using that prevents the errors I'm having?

What is the correct way to declare modules & controllers, so that the order files are concatenated doesn't impact the code at runtime?

ed. ed.
Answer Source

One technique I sometimes use is to put declarations at the start of the concatenated file. I do this by putting them in a dedicated file that will be the first one to be picked up by the concatenation utility.


   .config(['$routeProvider', function ($router) {...});

   .controller('DepositFormCtrl', function($scope) {...});

May not be a good fit for all scenarios, but is simple to set up and understand.