Рефакторинг большой конфигурации модуля AngularJS в отдельные файлы

Проблема: Большой config()

Конфигурация моего приложения AngularJS растет довольно широко. Как бы вы реорганизовали следующее в отдельные файлы?

// app.js
angular.module('myApp')
    .config(function($urlRouterProvider, $stateProvider, $httpProvider) {
        // Configure routing (uiRouter)
        $urlRouterProvider.when('/site', '/site/welcome');
        $stateProvider.state('main', ...
        ...

        // Configure http interceptors
        $httpProvider.interceptors.push(function () {              
            ...
        });
    });

Вариант 1. Несколько config() s

Я знаю, что у меня может быть несколько config() и поместить их в отдельные файлы следующим образом:

// app.js
angular.module('myApp');

// routerConfiguration.js
angular.module('myApp')
    .config(function($urlRouterProvider, $stateProvider) {
        // Configure routing (uiRouter)
        $urlRouterProvider.when('/site', '/site/welcome');
        $stateProvider.state('main', ...
        ...

// httpInterceptorConfig.js
angular.module('myApp')
    .config(function($httpProvider) {
        // Configure http interceptors
        $httpProvider.interceptors.push(function () {              
            ...
        });
    });

Что мне не нравится в этом, так это то, что в исходном app.js нет способа получить обзор того, что запускается при запуске.


Вариант 2. Вставить что-то

Я бы предпочел сделать что-то подобное, потому что было бы легче увидеть, что настроено, прямо в app.js. Однако я знаю, что это невозможно, поскольку мы не можем внедрять службы в config().

Могу ли я использовать поставщиков для решения этой проблемы? Есть ли лучший способ?

// app.js
angular.module('myApp')
    .config(function(routerConfig, httpInterceptorConfig) {
        routerConfig.setup();
        httpInterceptorConfig.setup();
    });

// routerConfig.js
angular.module('myApp')
    .factory('routerConfig', function($urlRouterProvider, $stateProvider) {
        return {
            setup: function() {
                // Configure routing (uiRouter)
                $urlRouterProvider.when('/site', '/site/welcome');
                $stateProvider.state('main', ...
                ...
            }
        };
    });
});

// httpInterceptorConfig.js
angular.module('myApp')
    .factory('httpInterceptorConfig', function($httpProvider) {
        return {
            setup: function() {
                // Configure http interceptors
                $httpProvider.interceptors.push(function () {              
                ...
            }
        };
    });
});

Ответы

Ответ 1

Вы можете использовать .constant как зависимость в .config, поэтому вы можете использовать объявление конфигурации как ручной составной корень. Например:

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) {          
        ...
    });

Недостатки этого подхода заключаются в том, что вы должны вставлять все ваши зависимости конфигурации в корневую конфигурационную функцию, а затем вручную вводить их в свои постоянные функции конфигурации. Если у вас много разных конфигурационных функций, это может стать беспорядочным. Он также может выглядеть примерно так: ваши конфигурационные функции имеют зависимости, введенные Angular, но на самом деле вы делаете это вручную. Вам нужно будет убедиться, что вы не забываете выполнять ручную проводку каждый раз, когда вы добавляете новую конфигурационную функцию.

Мой предпочтительный подход состоит только в том, чтобы иметь папку с именем "config", содержащую исключительно конфигурационные вызовы.

Ответ 2

Я бы посмотрел на browserify

Он позволяет вам использовать разметку, чтобы требовать модули в вашем javascript.

Это позволит вам разбить ваш config на несколько файлов, сохраняя их вместе (см. пример).

browserify компилирует ваш javascript в один пакет bundle.js путем рекурсивного отслеживания запросов из основного файла javascript.

Затем вам нужно включить <script src="bundle.js"></script> в свой 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']);

Структура файла

  • MYAPP
    • конфигурации
      • route.js
      • httpProvider.js
    • myApp.js
    • index.html