Имеет ли смысл использовать Require.js с Angular.js?
Я новичок в Angular.js и пытаюсь понять, чем он отличается от Backbone.js... Мы использовали для управления зависимостями наших пакетов с помощью Require.js при использовании Backbone. Имеет ли смысл делать то же самое с Angular.js?
14 ответов
Да имеет смысл использовать angular.js
вместе с require.js
где вы можете использовать require.js
для модульных компонентов.
Я могу указать вам на начальный проект, который использует both angular.js and require.js
, Надеюсь, это поможет!
Чтобы переформулировать то, что я думаю, вопрос ОП на самом деле:
Если я создаю приложение в основном на Angular 1.x и (неявно) делаю это в эпоху Grunt/Gulp/Broccoli и Bower/NPM, и у меня может быть пара дополнительных библиотечных зависимостей, требуется ли для Require добавить четкие, специфичные значение, превышающее то, что я получаю, используя Angular без Require?
Или, говоря по-другому:
"Нужно ли Vanilla Angular Требовать эффективного управления базовой загрузкой компонентов Angular, если у меня есть другие способы обработки базовой загрузки скриптов? "
И я полагаю, что основной ответ на этот вопрос: "Нет, если у вас нет чего-то еще, и / или вы не можете использовать более новые, более современные инструменты".
Давайте с самого начала проясним ситуацию: RequireJS - это отличный инструмент, который решил некоторые очень важные проблемы и направил нас по пути к более масштабируемым, более профессиональным приложениям Javascript. Важно отметить, что это было впервые, когда многие люди столкнулись с концепцией модульности и выведения вещей из глобальной сферы видимости. Итак, если вы собираетесь создать приложение Javascript, которое необходимо масштабировать, то Require и шаблон AMD не являются плохими инструментами для этого.
Но есть ли что-то особенное в Angular, которое делает Require/AMD особенно подходящим? Нет. Фактически, Angular предоставляет вам свой собственный шаблон модульности и инкапсуляции, который во многих отношениях делает избыточными базовые функции модульности AMD. И интеграция модулей Angular в паттерн AMD не является невозможной, но она немного... привередлива. Вы определенно будете тратить время на то, чтобы эти две модели хорошо интегрировались.
Для некоторой перспективы от самой команды Angular, есть, от Брайана Форда, автора Angular Batarang и теперь члена основной команды Angular:
Я не рекомендую использовать RequireJS с AngularJS. Хотя это, конечно, возможно, я не видел ни одного случая, когда RequireJS был бы полезен на практике.
Итак, по очень специфическому вопросу AngularJS: Angular и Require/AMD ортогональны и местами перекрываются. Вы можете использовать их вместе, но нет никаких причин, конкретно связанных с природой / паттернами самого Angular.
Но как насчет базового управления внутренними и внешними зависимостями для масштабируемых приложений Javascript? Разве Требование не делает что-то действительно критическое для меня там?
Я рекомендую проверить Bower и NPM, и особенно NPM. Я не пытаюсь начать священную войну за сравнительные преимущества этих инструментов. Я просто хочу сказать: есть другие способы снять шкуру с этой кошки, и эти способы могут быть даже лучше, чем AMD/Require. (У них, конечно, гораздо более популярный импульс в конце 2015 года, особенно NPM, в сочетании с модулями ES6 или CommonJS. См. Связанный вопрос SO.)
А как насчет ленивой загрузки?
Обратите внимание, что отложенная загрузка и отложенная загрузка различаются. Ленивая загрузка Angular не означает, что вы извлекаете их прямо с сервера. В приложении в стиле Yeoman с автоматизацией javascript вы объединяете и минимизируете весь shebang в один файл. Они присутствуют, но не исполняются / не создаются, пока не понадобятся. Улучшения в скорости и пропускной способности, которые вы получаете от этого, значительно перевешивают любые предполагаемые улучшения от ленивой загрузки конкретного контроллера с 20 линиями. Фактически, потерянная задержка сети и накладные расходы передачи для этого контроллера будут на порядок больше, чем размер самого контроллера.
Но допустим, что вам действительно нужна отложенная загрузка, возможно, для нечасто используемых частей вашего приложения, таких как интерфейс администратора. Это очень законный случай. Требовать действительно может сделать это для вас. Но есть также много других, потенциально более гибких вариантов, которые выполняют то же самое. И Angular 2.0, по-видимому, позаботится об этом для нас, встроенных в маршрутизатор. ( Подробности.)
Но как насчет разработки моего локального устройства разработки?
Как я могу загрузить все свои десятки / сотни файлов сценариев без необходимости присоединять их все к index.html вручную?
Посмотрите на суб-генераторы в Yeoman-генератор-angular, или на шаблоны автоматизации, воплощенные в https://github.com/Swiip/generator-gulp-angular, или на стандартную автоматизацию Webpack для React. Они предоставляют вам чистый, масштабируемый способ: автоматически прикреплять файлы во время создания компонентов или просто автоматически захватывать их, если они присутствуют в определенных папках / соответствуют определенным шаблонам глобуса. Вам больше никогда не нужно думать о собственной загрузке скрипта, если у вас есть последние варианты.
Нижняя линия?
Require - отличный инструмент для определенных вещей. Но идите с зерном, когда это возможно, и разделяйте ваши проблемы, когда это возможно. Позвольте Angular позаботиться о собственном шаблоне модульности Angular и рассмотрите возможность использования модулей ES6 или CommonJS в качестве общего шаблона модульности. Пусть современные средства автоматизации беспокоятся о загрузке скриптов и управлении зависимостями. И позаботьтесь об асинхронной ленивой загрузке, а не путайте ее с двумя другими проблемами.
Тем не менее, если вы разрабатываете приложения для Angular, но по какой-то причине не можете установить Node на свой компьютер для использования инструментов автоматизации Javascript, то Require может быть хорошим альтернативным решением. И я видел действительно сложные установки, где люди хотят динамически загружать компоненты Angular, каждый из которых объявляет свои собственные зависимости или что-то в этом роде. И хотя я, вероятно, попытался бы решить эту проблему по-другому, я вижу достоинства этой идеи для этой конкретной ситуации.
Но в противном случае... когда вы начинаете с нуля с новым приложением Angular и гибкостью для создания современной среды автоматизации... у вас есть много других, более гибких, более современных опций.
(Обновляется неоднократно, чтобы не отставать от развивающейся сцены JS.)
Да, это имеет смысл.
Угловые модули не пытаются решить проблему упорядочения загрузки скрипта или ленивого извлечения скрипта. Эти цели ортогональны, и обе модульные системы могут жить бок о бок и выполнять свои цели.
Источник: Angular JS официальный сайт
Я считаю, что это субъективный вопрос, поэтому я выскажу свое субъективное мнение.
В Angular встроен механизм модульности. Когда вы создаете свое приложение, первое, что вы должны сделать, это
var app = angular.module("myApp");
а потом
app.directive(...);
app.controller(...);
app.service(...);
Если вы посмотрите на angular-seed, который является аккуратным стартовым приложением для angular, они разделили директивы, сервисы, контроллеры и т. Д. На разные модули, а затем загрузили эти модули как зависимости от вашего основного приложения.
Что-то вроде:
var app = angular.module("myApp",["Directives","Controllers","Services"];
Angular также лениво загружает эти модули (в память), а не их файлы сценариев.
С точки зрения отложенной загрузки файлов сценариев, если быть откровенным, если вы не пишете что-то очень большое, это было бы излишним, потому что angular по самой своей природе уменьшает объем написанного вами кода. Типичное приложение, написанное в большинстве других фреймворков, может ожидать сокращения LOC примерно на 30-50%, если оно написано в угловом формате.
Использование RequireJS с AngularJS имеет смысл, но только в том случае, если вы понимаете, как работает каждый из них в отношении внедрения зависимостей, поскольку, хотя оба они внедряют зависимости, они вводят совершенно разные вещи.
AngularJS имеет свою собственную систему зависимостей, которая позволяет вводить модули AngularJS во вновь созданный модуль для повторного использования реализаций. Допустим, вы создали "первый" модуль, который реализует AngularJS-фильтр "greet":
angular
.module('first', [])
.filter('greet', function() {
return function(name) {
return 'Hello, ' + name + '!';
}
});
А теперь давайте предположим, что вы хотите использовать фильтр "greet" в другом модуле под названием "second", который реализует фильтр "до свидания". Вы можете сделать это, вставив "первый" модуль во "второй" модуль:
angular
.module('second', ['first'])
.filter('goodbye', function() {
return function(name) {
return 'Good bye, ' + name + '!';
}
});
Дело в том, что для правильной работы без RequireJS вы должны убедиться, что "первый" модуль AngularJS загружен на страницу перед созданием "второго" модуля AngularJS. Цитирование документации:
В зависимости от модуля подразумевается, что требуемый модуль должен быть загружен до загрузки требуемого модуля.
В этом смысле, вот где RequireJS может помочь вам, так как RequireJS предоставляет чистый способ внедрения сценариев на страницу, помогая вам организовать зависимости между сценариями между собой.
Возвращаясь к "первому" и "второму" модулям AngularJS, вот как вы можете сделать это, используя RequireJS, разделяя модули на разные файлы, чтобы использовать загрузку зависимостей скрипта:
// firstModule.js file
define(['angular'], function(angular) {
angular
.module('first', [])
.filter('greet', function() {
return function(name) {
return 'Hello, ' + name + '!';
}
});
});
// secondModule.js file
define(['angular', 'firstModule'], function(angular) {
angular
.module('second', ['first'])
.filter('goodbye', function() {
return function(name) {
return 'Good bye, ' + name + '!';
}
});
});
Вы можете видеть, что мы зависим от файла "firstModule", который должен быть введен до того, как может быть выполнен контент обратного вызова RequireJS, для которого требуется "первый" модуль AngularJS, чтобы создать "второй" модуль AngularJS.
Примечание: для использования AngularJS внутри функции обратного вызова RequireJS необходимо настроить "angular" в файлах "firstModule" и "secondModule" и настроить его в конфигурации RequireJS для сопоставления "angular" с кодом библиотеки. Возможно, AngularJS также загружен на страницу традиционным способом (тэг скрипта), хотя и не дает преимуществ RequireJS.
Более подробная информация о поддержке RequireJS из ядра AngularJS версии 2.0 в моем блоге.
Основываясь на моем сообщении в блоге "Осмысление RequireJS с AngularJS", вот ссылка.
Как упомянул @ganaraj, AngularJS имеет в своей основе внедрение зависимостей. При создании приложений для игрушечных семян с и без RequireJS я лично обнаружил, что RequireJS, вероятно, был излишним для большинства случаев использования.
Это не означает, что RequireJS бесполезен из-за возможностей загрузки скриптов и поддержания чистоты базы кода во время разработки. Сочетание оптимизатора r.js ( https://github.com/jrburke/r.js) и Almond ( https://github.com/jrburke/almond) может создать очень тонкую историю загрузки скриптов. Однако, поскольку его функции управления зависимостями не так важны для angular в ядре вашего приложения, вы также можете оценить решения для загрузки скриптов на стороне клиента (HeadJS, LABjs, ...) или даже на стороне сервера (MVC4 Bundler, ...) для вашего конкретного применения.
Да, это так, особенно для очень больших SPA.
В некоторых случаях RequireJS является обязательным. Например, я разрабатываю приложения PhoneGap, используя AngularJS, который также использует Google Map API. Без загрузчика AMD, такого как RequireJS, приложение просто зависнет при запуске в автономном режиме, так как не сможет получить сценарии API Google Map. Загрузчик AMD дает мне возможность отобразить сообщение об ошибке пользователю.
Однако интеграция между AngularJS и RequireJS немного сложна. Я создал angularAMD, чтобы сделать этот процесс менее болезненным:
Короткий ответ, это имеет смысл. Недавно это обсуждалось в ng-conf 2014. Вот разговор на эту тему:
Имеет смысл использовать requirejs с angularjs, если вы планируете ленивую загрузку контроллеров и директив и т. Д., А также объединять несколько ленивых зависимостей в отдельные файлы сценариев для гораздо более быстрой ленивой загрузки. RequireJS имеет инструмент оптимизации, который облегчает объединение. См. http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/
Да, имеет смысл использовать requireJS с Angular, я потратил несколько дней, чтобы протестировать несколько технических решений.
Я сделал угловое семя с RequireJS на стороне сервера. Очень простой Я использую обозначение SHIM для не модуля AMD, а не AMD, потому что я думаю, что очень трудно иметь дело с двумя разными системами внедрения зависимости.
Я использую grunt и r.js для объединения файлов js на сервере, в зависимости от файла конфигурации (зависимости) SHIM. Поэтому я ссылаюсь только на один файл js в моем приложении.
Для получения дополнительной информации перейдите на мой github Angular Seed: https://github.com/matohawk/angular-seed-requirejs
Я бы не использовал Require.js. Приложения, которые я видел, которые делают это, запутывают много типов архитектуры шаблонов модулей. AMD, Revealing, различные варианты IIFE и т. Д. Существуют и другие способы загрузки по требованию, например, мод LoadOnDemand Angular. Добавление других вещей просто наполняет ваш код, полный бесполезности и создает низкое отношение сигнал / шум и делает ваш код трудным для чтения.
Вот подход, который я использую: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very-large-applications/
На странице показана возможная реализация AngularJS + RequireJS, где код разбит по функциям, а затем по типу компонента.
Ответ от Брайана Форда
AngularJS имеет свою собственную систему модулей, которая обычно не нуждается в чем-то вроде RJS.
Ссылка: https://github.com/yeoman/generator-angular/issues/40
Я думаю, что это зависит от сложности вашего проекта, так как angular в значительной степени модульный. Ваши контроллеры могут быть сопоставлены, и вы можете просто импортировать эти классы JavaScript на своей странице index.html.
Но в случае, если ваш проект станет больше. Или вы предвидите такой сценарий, вам следует объединить angular с requirejs. В этой статье вы можете увидеть демонстрационное приложение для такой интеграции.