config()
The config of my AngularJS app is growing quite large. How would you refactor the following into separate files?
I would look at browserify
It allows you to use markup to require modules in your javascript.
This would allow you to break up your config
into multiple files while keeping them together (see example).
browserify
compiles your javascript into a single bundle.js by recursively tracing the requires from your main javascript file.
You then only need to include <script src="bundle.js"></script>
on your index.html
Javascript
'use strict';
require('angular/angular');
require('angular-ui/ui-router');
var app = angular.module('vw', ['ui.router', 'myApp.feature1', 'myApp.feature2'])
.config(require('./config/route'))
.config(require('./config/httpProvider'));
angular.bootstrap(document, ['myApp']);
File Structure
You can use .constant
as a dependency in a .config
, so you could use the config declaration as a manual composition root. For example:
angular.module('myApp')
.config(function($urlRouterProvider, $stateProvider, $httpProvider,
routerConfig, httpInterceptorConfig) {
routerConfig($urlRouterProvider, $stateProvider);
httpInterceptorConfig($httpProvider);
});
// routerConfig.js
angular.module('myApp')
.constant('routerConfig', function($urlRouterProvider, $stateProvider) {
...
});
// httpInterceptorConfig.js
angular.module('myApp')
.constant('httpInterceptorConfig', function($httpProvider) {
...
});
Drawbacks to this approach are that you have to inject all of your config dependencies into the root config function, then manually inject them into your constant config functions. If you have a lot of different config functions, this could get messy. It can also look kind of like your config functions are having dependencies injected by Angular, but in fact you are doing it manually. You would need to make sure you remember to do the manual wiring every time you add a new config function.
My preferred approach is just to have a folder called "config" containing exclusively config calls.
I just did this recently with a provider.
angular.module('EventView')
.provider('routing', ['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
this.init = function() {
// For any unmatched url, redirect to /home
$urlRouterProvider.otherwise('/home');
// Now set up the states
$stateProvider
.state('login', {
url: '/account/login?{redirectUrl}',
controller: 'loginCtrl',
templateUrl: 'partials/account/login/login.tpl.html'
})
}
// has to be here
this.$get = function() {
return {};
};
}
]);
In the config you can just call the function.
angular.module('EventView').config(['routingProvider', function (routingProvider) {
routingProvider.init();
}
]);
There are two gotachas, first that the name of the provider adds provider to it when you reference from the config and the second is that you have to implement the $get and return a function.
Good luck!