2014-10-09 7 views
6

Я работаю над проектом с угловым и браунирующим, это первый раз, когда я использую эти два инструмента вместе, поэтому мне бы хотелось, чтобы некоторые советы, по которым путь require файлов с браузером ,Требовать шаблон Browserify/Angular

Мы можем импортировать эти файлы по-разному, До сих пор я экспериментировал так:

Угловая App:

app 
    _follow 
    - followController.js 
    - followDirective.js 
    - followService.js 
    - require.js 
- app.js 

Для каждой папки с в файлы для плагина я создал require.js файл и в нем мне нужны все файлы этой папки. Как так:

var mnm = require('angular').module('mnm'); 

mnm.factory('FollowService', ['Restangular',require('./followService')]); 
mnm.controller('FollowController',['$scope','FollowService',require('./followController')]) 
mnm.directive('mnmFollowers', ['FollowService',require('./followDirective')]); 

, а затем требуют, чтобы все require.js файлы в уникальный файл с именем app.js, который будет генерировать bundle.js

Вопрос:

Этот способ требует файлов может быть хорошей структурой , или это будет иметь некоторые проблемы, когда мне нужно проверить? Я бы хотел, чтобы ваш путь к достижению хорошей структуры с угловым и браузером

ответ

5

AngularJS и браузер не являются, к сожалению, отличным сочетанием. Конечно, не нравится React и браузер, но я отвлекаюсь.

Что сработало для меня, так это то, что каждый файл является модулем AngularJS (поскольку каждый файл уже является модулем CommonJS) и файлы экспортируют свое имя модуля AngularJS.

Так что ваш пример будет выглядеть следующим образом:

app/ 
    app.js 
    follow/ 
    controllers.js 
    directives.js 
    services.js 
    index.js 

app.js будет выглядеть примерно так:

var angular = require('angular'); 
var app = angular.module('mnm', [ 
    require('./follow') 
]); 
// more code here 
angular.bootstrap(document.body, ['mnm']); 

follow/index.js будет выглядеть примерно так:

var angular = require('angular'); 
var app = angular.module('mnm.follow', [ 
    require('./controllers'), 
    require('./directives'), 
    require('./services') 
]); 
module.exports = app.name; 

follow/controllers.js будет выглядеть примерно так:

var angular = require('angular'); 
var app = angular.module('mnm.follow.controllers', [ 
    require('./services'), // internal dependency 
    'ui.router' // external dependency from earlier require or <script/> 
    // more dependencies ... 
]); 
app.controller('FollowController', ['$scope', 'FollowService', function ...]); 
// more code here 
module.exports = app.name; 

И так далее.

Преимущество этого подхода в том, что вы сохраняете свои зависимости как можно более ясными (т. Е. Внутри модуля CommonJS, который им действительно нужен), а взаимно однозначное сопоставление между модами модулей CommonJS и именами модулей AngularJS предотвращает неприятные сюрпризы.

Наиболее очевидная проблема с вашим подходом заключается в том, что вы сохраняете фактические зависимости, которые будут вставляться отдельно от ожидающей их функции, поэтому, если зависимости функций изменяются, вам нужно коснуться двух файлов вместо одного. Это запах кода (т. Е. Плохая вещь).

Для проверки пригодности любой подход должен работать, поскольку модульная система Angular является по существу гигантским блобом и импортирует два модуля, которые определяют одно и то же имя, будут переопределять друг друга.


EDIT (через два года): Некоторые другие люди (как здесь и в других местах) предложили альтернативные подходы, так что я, вероятно, следует обратиться к ним и какие компромиссы:

  1. Есть один глобальный модуль AngularJS для всего вашего приложения и просто требуется для побочных эффектов (т. е. не имеют подмодулей экспорта ничего, кроме как манипулировать глобальным угловым объектом).

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

  2. Объедините свой код приложения AngularJS до, передавая его для браузера.

    Это наиболее буквальное решение для «давайте объединим AngularJS и Browserify». Это правильный подход, если вы начинаете с традиционной позиции «просто слепо конкатенировать свои файлы приложений» AngularJS и хотите добавить Browserify для сторонних библиотек, поэтому я предполагаю, что это делает ее действительной.

    Что касается структуры вашего приложения, это ничего не улучшает, добавляя Browserify.

  3. Как 1, но с каждым index.js, определяющим собственный подмодуль AngularJS.

    Это подход с использованием шаблонов, предложенный Брайаном Огденом. Это страдает от всех недостатков 1, но создает некоторое подобие иерархии внутри AngularJS тем, что по крайней мере у вас есть более одного модуля AngularJS, а имена модулей AngularJS действительно соответствуют вашей структуре каталогов.

    Однако главный недостаток заключается в том, что у вас теперь есть два набора пространств имен, о которых вам нужно беспокоиться (ваши фактические модули и модули AngularJS), но ничто не обеспечивает согласованности между ними. Вам не только нужно помнить, что нужно импортировать правильные модули (которые в очередной раз опираются на побочные эффекты), но вы также должны помнить о том, чтобы добавить их ко всем правильным спискам и добавить один и тот же шаблон в каждый новый файл. Это делает рефакторинг невероятно громоздким и делает этот худший вариант, на мой взгляд.

Если бы я должен был выбрать сегодня, я бы с 2, потому что он отдает всю отговорку AngularJS и Browserify возможности быть унифицировано и просто оставляет как делать свое дело. Плюс, если у вас уже есть система сборки AngularJS, это буквально означает добавление дополнительного шага для Browserify.

Если вы не наследуете базу данных AngularJS и хотите знать, какой подход лучше всего подходит для запуска нового проекта: не запускайте новый проект в AngularJS. Либо выберите Angular2, который поддерживает реальную модульную систему из коробки, либо переключитесь на React или Ember, которые не страдают от этой проблемы.

+0

Это отлично работает - спасибо за проходящие через время, чтобы сделать это. Мне удалось сделать что-то очень похожее на require.js, и вы помогли мне перейти от безумия AMD: D – marksyzm

+0

@AlanPlum ничего себе не удивительно, что вам не нравится, как Browserify смешивается с Angular. Это какой-то сумасшедший код, а не хороший образец. нет необходимости в modules.exports и необходимости установки в экземплярах углового модуля ... проверьте это для лучшего шаблона с помощью AngularJS и выполните прокрутку https: // github.com/Sweetog/yet-another-angular-patplate –

+0

После того, как вы добавите их в нужные списки, вам не нужно когда-либо забывать добавлять их снова, а шаблонный шаблон не относится ко всем файлам, а только к модулям и index.js за как каждый каталог является угловым модулем –

0

Я пытался использовать браузер с помощью Angular, но нашел, что он немного запутан. Мне не понравился шаблон создания именованного сервиса/контроллера, после чего он потребовал его из другого места, например.

angular.module('myApp').controller('charts', require('./charts')); 

Имя/определение контроллера находится в одном файле, но сама функция находится в другом.Кроме того, наличие большого количества файлов index.js делает его действительно запутанным, если вы открываете много файлов в среде IDE.

Так я соединял этот глоток плагин, gulp-require-angular который позволяет писать Угловым используя стандартное Угловое синтаксис, все JS файлов, которые содержат угловые модули и зависимости угловых модулей, которые появляются в главном дереве модуля зависимостей являются require() «D в формируемый который вы затем используете в качестве файла ввода для браузера.

Вы по-прежнему можете использовать require() в своей базе кода, чтобы по требованию использовать внешние библиотеки (например, lodash) в сервисах/фильтрах/директивах.

Here's the latest Angular seed forked and updatedgulp-require-angular.

+0

Я прошу вас, потому что вы хорошо поработали с этим плагином (я не пробовал, но выглядел хорошо), но я остался бы с браузером , – Fabrizio

0

Я использовал гибридный подход, похожий на pluma. Я создал нг-модули, как так:

var name = 'app.core' 

angular.module(name, []) 
.service('srvc', ['$rootScope', '$http', require('./path/to/srvc')) 
.service('srvc2', ['$rootScope', '$http', require('./path/to/srvc2')) 
.config... 
.etc 

module.exports = name 

Я думаю, что разница в том, что я не определяю отдельные нг-модулей в зависимости к основным нг-модулю, в данном случае я бы не определить службу как ng-module, а затем перечислить его как элемент app.core ng-module. Я стараюсь держать его как можно ровнее:

//srvc.js - see below 
module.exports = function($rootScope, $http) 
{ 
    var api = {}; 
    api.getAppData = function(){ ... } 
    api.doSomething = function(){ ... } 
    return api; 
} 

Что касается комментария кодового запаха, я не согласен. Хотя это дополнительный шаг, он позволяет отличную конфигурацию с точки зрения тестирования против mock-сервисов. Например я использую это совсем немного для тестирования Agains услуг, которые не могут иметь существующий серверный API готовый:

angular.module(name, []) 
// .service('srvc', ['$rootScope', '$http', require('./path/to/srvc')) 
    .service('srvc', ['$rootScope', '$http', require('./path/to/mockSrvc')) 

Таким образом, любой контроллер или объект зависит от srvc не знает, какой он получает. Я мог видеть, что это немного запутанно с точки зрения услуг, зависящих от других сервисов, но для меня это плохой дизайн. Я предпочитаю использовать систему событий ng для связи между ними. услуг, чтобы вы поддерживали связь.

0

Ответ Алана Слима - это не отличный ответ или, по крайней мере, не большая демонстрация модулей CommonJS и Browserify с помощью Angular. Утверждение, что Browserify не хорошо сочетается с Angular, по сравнению с React, просто неверно.

Browserify и образец модуля CommonJS отлично работают с Angular, позволяя вам организовывать функции вместо типов, сохранять vars вне глобальной сферы и легко распределять угловые модули в приложениях. Не говоря уже о том, что вам больше не нужно добавлять один HTML-код <script> в ваш HTML-код, благодаря Browserify, чтобы найти все ваши зависимости.

Отказоустойчивый ответ Алана Плаума не требует от каждого индекса.js для каждой папки диктует зависимости для Угловых модулей, контроллеров, сервисов, конфигураций, маршрутов и т. Д. Нет необходимости в одном требовании в Угловом .module, а также один модуль.exports, как в контексте, о котором говорит Алан Плум.

Смотрите здесь для лучшего рисунка модуля для углового с помощью Browserify: https://github.com/Sweetog/yet-another-angular-boilerplate

+0

Я удалил свои комментарии в пользу внесения изменений в свой ответ, чтобы ответить на ваше предложение (и другие, сделанные в другом месте). –

Смежные вопросы