I am confused about the proper way to implement requireJS (and the r.js optimizer) into a very large AngularJS SPA. I would like some advice on how to organize the project so I get the benefit of AMD modularization, but not over complicate things (wrapping angular modules inside require js define
d modules, which are all dumped into an optimized .js file...).
I have a few different categories of files I'm dealing with:
Using r.js to concat and minify all the vendor stuff together seems like a no-brainer, but when I started adding in all the other code, I felt like my project got muddy. For example, I have an Auth service, a couple controllers, and my vendor dependencies (jquery...). So my main.js
that require looks at is sorta like this:
require.config({
paths: {
// load vendor libraries
'domReady': '../vendor/requirejs-domready/domReady',
'angular': '../vendor/angular/angular',
'jquery': '../vendor/jquery/jquery.min',
requireLib: '../vendor/requirejs/require'
... lots of these
//load app code
'app': '../app/app',
'AuthCtrl': '../app/modules/auth/AuthCtrl',
'UserCtrl': '../app/modules/auth/UserCtrl',
'SettingsCtrl': '../app/modules/auth/SettingsCtrl',
// potentially dozens and dozens of these...
//load auth library
'auth': '../app/modules/common/auth',
'analytics' '../analytics'
},
include: ['domReady', 'requireLib'],
shim: {
'angular': {
exports: 'angular'
}
}
...
});
Currently, I have been dumping all of the code from all 3 'categories' above into 1 big uglified js file.
What I'm not happy with is I feel like my controller is starting to need a laundry list of module dependencies:
require('app',[
'angular',
'jquery',
'AuthCtrl',
'UserCtrl',
'SettingsCtrl',
' ... potentially dozens? '
...
], function (angular, $, Auth, user, settings, ...potentially dozens?) {
'use strict';
return angular.module('ngAD', ['AuthCtrl', 'UserCtrl', 'SettingsCtrl' ...]);
});
So my question is two fold I guess:
There should be no need to do all of that.
I used this as a starting point https://github.com/Matthew-Odette/angular-require-bootstrap-seed
Then all that is required is to add controllers and services to the require section at the end of the AMD file. e.g.
require(
[
// Dependencies from lib
'angular',
'ngRoute',
'../lib/less.min.1.5.0',
// Angular directives/controllers/services
'app',
'core/viewHomeController',
'core/commonRoutes',
'core/header',
'events/events-ctrl
],
function (angular) {
var AppRoot = angular.element(document.getElementById('ng-app'));
AppRoot.attr('ng-controller','AppCtrl');
angular.bootstrap(document, ['TheApp']);
});
events-ctrl.js being new controller/service that's been added, further controllers/services would be added the same way
Then the controllers/services needs to be wrapped in require code e.g. this is beginning of events-ctrl.js
define(['app'], function (app) {
app.factory('EventService', function($resource) {
return $resource('/api/events/:id');
});
app.controller('EventListCtrl', ['$scope', '$modal', 'EventService', function($scope, $modal, EventService) {
console.log('EventListCtrl working');
...