Имеет ли смысл использовать Require.js с Angular.js? [закрыто]

443

Я новичок в Angular.js и пытаюсь понять, чем он отличается от Backbone.js ... Мы использовали для управления зависимостями наших пакетов с помощью Require.js при использовании Backbone. Имеет ли смысл делать то же самое с Angular.js?

Franck
источник
Еще один блог и семян проекта: startersquad.com/blog/angularjs-requirejs
Iwein
19
Нет - не используйте require.js ИЛИ не просматривайте с Angular.JS, в этом просто нет необходимости - AngularJS имеет модульную систему, а использование другой модульной системы над ней сделает вашу жизнь излишне сложной. Я следил за ответами в этой теме и потратил слишком много часов на то, что было совершенно ненужным. Пожалуйста , прочитайте эту статью , которая объясняет , почему нет: medium.com/@dickeyxxx/...
VitalyB
Прочитайте это, чтобы понять разницу между угловыми и обязательными модулями juristr.com/blog/2014/07/lazy-angular-modules
pilavdzice
1
Вот отличное видео, которое объясняет, почему это хорошая идея, и показывает, как использовать requireJS с angularJS youtube.com/watch?v=4yulGISBF8w#t=142
gskalinskii
2
@VitalyB Хорошая статья! Я предпочитаю загружать приложения небольшими порциями. Это скоро ничего не будет стоить . Черт возьми, это ничего не стоит для меня прямо сейчас.
2015 г.,

Ответы:

224

Да, имеет смысл использовать angular.jsвместе с тем, require.jsгде вы можете использовать require.jsдля модульности компонентов.

Есть начальный проект, который использует both angular.js and require.js.

Anshu
источник
108
Упомянутый выше начальный проект не затрагивался в течение года, поэтому я создал новый, используя последние версии AngularJS и RequireJS, с полной поддержкой тестирования на основе тетакуляра.
tnajdek
2
@tnajdek, я обновил ссылку в ответе Аншу, чтобы указать на ту, которую вы предлагаете.
Дэвид Риверс
7
Обратите внимание, что ни один из этих начальных проектов не одобрен командой Angular. Require - это шаблон, который имеет больше смысла в других контекстах, и использование его в Angular не является, IMHO, лучшей практикой.
XML
2
В книге О'Рейли AngularJS Брэда Грина и Шьяма Сешадри (выпущенной в апреле этого года) также рекомендуется добавить RequireJS на ранних этапах развития проекта Angular, и детали довольно четко изложены.
Бьорке
1
Я бы предпочел сделать все во время сборки 1. browserify.org 2. npmjs.org/package/gulp-angular-filesort
A-Dubb
150

Чтобы переформулировать то, что я думаю, вопрос ОП на самом деле:

Если я создаю приложение в основном на 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 не является невозможной, но она немного ... привередлива. Вы определенно будете тратить время на то, чтобы эти две модели хорошо интегрировались.

Для некоторых из перспективы самого угловой команды, есть это , от Брайана Форда, автора углового Batarang и теперь члена угловой основной команды:

Я не рекомендую использовать 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, по-видимому, позаботится об этом для нас, встроенных в маршрутизатор . ( Подробности .)

Но как насчет разработки моего локального dev boxen?

Как я могу загрузить все свои десятки / сотни файлов сценариев без необходимости присоединять их все к index.html вручную?

Посмотрите на суб-генераторы в Yeoman-генератор-angular, или на шаблоны автоматизации, воплощенные в generator-gulp-angular , или на стандартную автоматизацию Webpack для React. Они предоставляют вам чистый, масштабируемый способ: либо автоматически прикреплять файлы во время создания компонентов, либо просто автоматически захватывать их, если они присутствуют в определенных папках / соответствуют определенным шаблонам глобуса. Вам больше никогда не нужно думать о собственной загрузке скрипта, если у вас есть последние опции.

Нижняя граница?

Require - отличный инструмент для определенных вещей. Но идите с зерном, когда это возможно, и разделяйте ваши проблемы, когда это возможно. Позвольте Angular позаботиться о собственном шаблоне модульности Angular и рассмотрите возможность использования модулей ES6 или CommonJS в качестве общего шаблона модульности. Пусть современные средства автоматизации беспокоятся о загрузке скриптов и управлении зависимостями. И позаботьтесь об асинхронной ленивой загрузке, а не путайте ее с двумя другими проблемами.

Тем не менее, если вы разрабатываете приложения для Angular, но по какой-то причине не можете установить Node на свой компьютер для использования инструментов автоматизации Javascript, то Require может быть хорошим альтернативным решением. И я видел действительно сложные установки, где люди хотят динамически загружать компоненты Angular, каждый из которых объявляет свои собственные зависимости или что-то в этом роде. И хотя я, вероятно, попытался бы решить эту проблему по-другому, я вижу преимущества этой идеи для этой конкретной ситуации.

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

(Обновляется неоднократно, чтобы не отставать от развивающейся сцены JS.)

XML
источник
1
В начальном проекте NG-Boilerplate ( github.com/ngbp/ngbp ) также создается одностраничное веб-приложение с одним файлом js. Использование манифеста HTML5 гарантирует, что этот файл загружается только один раз для каждой версии.
Федерико Эллес
2
Хотя, как всегда, <я> это зависит </ I>. Многие люди используют Require для всей своей архитектуры, и им необходимо интегрировать Angular в эту экосистему. Это совсем другая ситуация, чем когда вы создаете приложения изолированно.
Дейв Никол
2
Согласовано. Но основной смысл OP выглядит следующим образом: «Если я создаю приложение преимущественно на Angular и (неявно) делаю это в эпоху Grunt, и у меня может быть пара дополнительных библиотечных зависимостей, требуется ли Require добавить четкое, конкретное значение помимо что я получаю, используя Angular без Require? " И я верю, ответ: нет. Если у вас огромное приложение с 40 внешними зависимостями, или вы не можете контролировать свою среду CI, или ваш босс обожает Require, или вы обожаете Require, или Angular - это всего лишь одна часть более крупного приложения и т. Д., И т. Д., То YMMV.
XML
1
Но так как он, кажется, не задает эти вопросы, и поскольку он просто упоминает альтернативный контекст приложения Backbone, он, похоже, спрашивает: «Требуется ли Vanilla Angular Требовать эффективного управления его компонентами?» И ответ таков: «Нет, если у вас не происходит что-то еще». Кроме того, этот вопрос возник на пороге движения Javascript CI, в котором мы получили гораздо лучшие способы справиться с базовой, физической «загрузкой сценариев». Если эта проблема решена, Require в основном касается сопоставления зависимостей и инкапсуляции. Angular делает обе эти вещи для вас.
XML
Google использует ленивую загрузку в некоторых своих проектах AngularJS, потому что в противном случае пользователь будет загружать 24 МБ файлов при первой загрузке страницы (и это с файлами, увеличенными и сцепленными). Так что да, в сложных приложениях не просто объединить все разделы, когда есть разделы, которые пользователь не будет открывать при каждом посещении.
ngDeveloper
136

Да, это имеет смысл.

Угловые модули не пытаются решить проблему упорядочения загрузки скрипта или ленивого извлечения скрипта. Эти цели являются ортогональными, и обе модульные системы могут жить бок о бок и выполнять свои цели.

Источник: Angular JS официальный сайт

Тиаго Рейс
источник
6
Если вы используете один модуль на файл js, вы можете загрузить свой угловой модуль в любом порядке. Но если вы хотите поместить, например, разные сервисы в разные js-файлы, но хотите прикрепить их к одному и тому же угловому модулю, вы должны загрузить объявление модуля перед объявлением сервисов. Так что это архитектурное решение.
Матогавк
@Tiago: Пожалуйста, предоставьте ссылку на место, откуда вы это взяли. Я не могу найти это нигде. Я предполагаю, что это было из более ранней версии документов Angular, до того, как шаблоны Angular стали настолько хорошо развиты, и до того, как стало ясно, что есть существенные преимущества от использования Require, по крайней мере для компонентов Angular.
XML
@XMLilley: можете ли вы предоставить ссылку, объясняющую преимущества избегания Require при использовании Angular? Я решаю, использовать ли Require в моем проекте, и это звучит так, как будто это будет полезно.
Тревор,
1
Мне было неясно в моем языке здесь: есть существенные преимущества в использовании собственных встроенных в Angular модулей-загрузчиков и в том, что касается структуры шаблонов Angular. Вопрос не в том, стоит ли избегать Require, а в том, есть ли смысл добавлять дополнительный уровень сложности. Что ясно, так это то, что встроенные шаблоны Angular легко и элегантно удовлетворят необходимость загрузки собственных модулей Angular. Если Require служит для загрузки модулей вне Angular-контекста, пусть будет так. Но использование Require для Angular не имеет смысла.
XML
6
@XMLilley все, что делает Angular, - это внедрение зависимости. Фактическая загрузка модуля - ваша ответственность. Вы можете сделать это, либо добавив тег script, используя скрипт сборки, либо используя requirejs. Система угловых модулей не имеет мнения по этому поводу.
gillesruppert
57

Я считаю, что это субъективный вопрос, поэтому я выскажу свое субъективное мнение.

В 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%, если оно написано в угловом формате.

ganaraj
источник
5
Действительно, лучше настроить службы в Angular.js, чем загружать модули с помощью Require.js. Это облегчает игру с $ scope и сервисами, так как я играл с Socket.io
Марко Годинес
33

Использование 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" , вот ссылка .

leog
источник
2
На самом деле лучше, если включить ссылку, чтобы суммировать содержание ссылки здесь, на переполнение стека. Если ваша ссылка когда-нибудь прекратится, что делают ссылки в Интернете, ваш ответ здесь будет бесполезен для будущих посетителей. Рассмотрите возможность редактирования, чтобы внести резюме и улучшить этот пост. Удачи!
jmort253
3
Ну вот, спасибо, jmort253.
Leog
Спасибо за внесение этих изменений и объяснение того, как RequireJS может помочь управлять зависимостями, чтобы избежать проблем с Angular, пытающегося загрузить то, что еще не существует.
jmort253
Я полностью согласен, лучше использовать этот подход для больших приложений, если в вашем приложении не будет нескольких тегов <script>.
I.Tyger
21

Как упомянул @ganaraj, AngularJS имеет в своей основе внедрение зависимостей. При создании приложений для игрушечных семян с и без RequireJS я лично обнаружил, что RequireJS, вероятно, был излишним для большинства случаев использования.

Это не означает, что RequireJS бесполезен из-за возможностей загрузки скриптов и поддержания чистоты базы кода во время разработки. Объединение оптимизатора r.js ( https://github.com/jrburke/r.js ) с Almond ( https://github.com/jrburke/almond ) может создать очень тонкую историю загрузки скриптов. Однако, поскольку его функции управления зависимостями не так важны для angular в ядре вашего приложения, вы также можете оценить решения для загрузки скриптов на стороне клиента (HeadJS, LABjs, ...) или даже на стороне сервера (MVC4 Bundler, ...) для вашего конкретного применения.

johlrich
источник
17

Да, это так, особенно для очень больших SPA.

В некоторых случаях RequireJS является обязательным. Например, я разрабатываю приложения PhoneGap, используя AngularJS, который также использует Google Map API. Без загрузчика AMD, такого как RequireJS, приложение просто зависнет при запуске в автономном режиме, так как не сможет получить сценарии API Google Map. Загрузчик AMD дает мне возможность отобразить сообщение об ошибке пользователю.

Однако интеграция между AngularJS и RequireJS немного сложнее. Я создал angularAMD, чтобы сделать этот процесс менее болезненным:

http://marcoslin.github.io/angularAMD/

marcoseu
источник
7

Имеет смысл использовать requirejs с angularjs, если вы планируете ленивую загрузку контроллеров и директив и т. Д., А также объединять несколько ленивых зависимостей в отдельные файлы сценариев для гораздо более быстрой ленивой загрузки. RequireJS имеет инструмент оптимизации, который облегчает объединение. Смотрите http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/

ify.io
источник
7

Да, имеет смысл использовать requireJS с Angular, я потратил несколько дней, чтобы протестировать несколько технических решений.

Я сделал угловое семя с RequireJS на стороне сервера. Очень простой Я использую обозначение SHIM для модуля AMD, а не для AMD, потому что я думаю, что очень трудно иметь дело с двумя разными системами внедрения Dependency.

Я использую grunt и r.js для объединения файлов js на сервере, в зависимости от файла конфигурации (зависимости) SHIM. Поэтому я ссылаюсь только на один файл js в моем приложении.

Для получения дополнительной информации перейдите на мой github Angular Seed: https://github.com/matohawk/angular-seed-requirejs

Matohawk
источник
3

Я бы не использовал Require.js. Приложения, которые я видел, которые делают это, запутывают много типов архитектуры шаблонов модулей. AMD, Revealing, различные варианты IIFE и т. Д. Существуют и другие способы загрузки по требованию, например мод LoadOnDemand Angular . Добавление других вещей просто наполняет ваш код, полный бесполезности и создает низкое отношение сигнал / шум и делает ваш код трудным для чтения.

Джулия Энн Джейкобс
источник
2

Вот подход, который я использую: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very-large-applications/

На странице показана возможная реализация AngularJS + RequireJS, где код разбит по функциям, а затем по типу компонента.

Ави Хаят
источник
3
Даже когда ссылка дает информацию, чтобы ответить на вопрос, объяснение того, что показывает страница, является наилучшей практикой.
juliocesar
0

Я думаю, что это зависит от сложности вашего проекта, так как angular в значительной степени модульный. Ваши контроллеры могут быть сопоставлены, и вы можете просто импортировать эти классы JavaScript на своей странице index.html.

Но в случае, если ваш проект станет больше. Или вы предвидите такой сценарий, вам следует объединить angular с requirejs. В этой статье вы можете увидеть демонстрационное приложение для такой интеграции.

lastboy
источник