web-dev-qa-db-fra.com

Est-il judicieux d'utiliser Require.js avec Angular.js?

Je suis un débutant sur Angular.js et j'essaie de comprendre en quoi c'est différent de Backbone.js ... Nous avions l'habitude de gérer nos dépendances de paquets avec Require.js lorsque nous utilisions Backbone. Est-il judicieux de faire la même chose avec Angular.js?

443
Franck

Oui, il est judicieux d'utiliser angular.js avec require.js, dans lequel vous pouvez utiliser require.js pour la modularisation des composants.

Je peux vous indiquer un projet pilote qui utilise both angular.js and require.js. J'espère que ça t'as aidé!

223
Anshu

Pour reformuler ce que je pense que la question du PO est vraiment:

Si je construis une application principalement dans Angular 1.x, et ce (implicitement) à l’ère de Grunt/Gulp/Broccoli et Bower/NPM, et que j’ai peut-être quelques dépendances supplémentaires à la bibliothèque, Require ajoute-t-il une valeur claire et spécifique au-delà de ce que je reçois en utilisant Angular sans Require?

Ou, autrement dit:

"Vanilla Angular a-t-il besoin de gérer efficacement le chargement de composant de base Angular, si j’ai d’autres moyens de gérer le chargement de script de base? "

Et je crois que la réponse fondamentale à cette question est la suivante: "pas à moins que vous n'ayez autre chose à faire et/ou que vous ne puissiez pas utiliser de nouveaux outils plus modernes".

Soyons clairs dès le départ: RequireJS est un excellent outil qui résout des problèmes très importants et nous a ouvert la voie vers des applications Javascript plus évolutives et plus professionnelles. Fait important, c’était la première fois que de nombreuses personnes rencontraient le concept de modularisation et de sortir des choses du monde entier. Donc, si vous voulez créer une application Javascript qui doit évoluer, alors Require et le modèle AMD ne sont pas de mauvais outils pour le faire.

Mais existe-t-il quelque chose de particulier à propos de Angular qui rend Require/AMD particulièrement adapté? Non. En fait, Angular vous fournit ses propres modèles de modularisation et d’encapsulation, qui rendent à bien des égards redondants les fonctionnalités de base de la modularisation d’AMD. Et intégrer des modules Angular dans le pattern AMD n’est pas impossible, mais c’est un peu ... capricieux. Vous passerez certainement du temps à bien intégrer les deux modèles.

Pour certaines perspectives de l'équipe Angular elle-même, il y a this , de Brian Ford, auteur du Angular Batarang et maintenant membre du Angular équipe de base:

Je ne recommande pas d'utiliser RequireJS avec AngularJS. Bien que ce soit certainement possible, je n'ai jamais vu de cas où RequireJS ait été bénéfique dans la pratique.

Donc, sur la question très spécifique de AngularJS: Angular et Require/AMD sont orthogonaux et se chevauchent par endroits. Vous pouvez les utiliser ensemble, mais il n'y a pas de raison spécifiquement liée à la nature/modèles de Angular elle-même.

Mais qu'en est-il de la gestion de base des dépendances internes et externes pour des applications Javascript évolutives? Exige-t-il quelque chose de vraiment critique pour moi là-bas?

Je recommande de vérifier Bower et NPM, et en particulier NPM. Je n'essaie pas de déclencher une guerre sainte sur les avantages comparatifs de ces outils. Je veux simplement dire: il y a d'autres moyens de peauner ce chat, et ces moyens peuvent être encore meilleurs que AMD/Require. (Ils ont certainement beaucoup plus de succès à la fin de 2015, en particulier le NMP, associé à des modules ES6 ou CommonJS. Voir related SO question .)

Qu'en est-il du chargement paresseux?

Notez que le chargement par la charge et le téléchargement par la charge sont différents. Le chargement paresseux d'Angular ne signifie pas que vous les extrayez directement du serveur. Dans une application de style yeoman avec une automatisation javascript, vous concaténez et réduisez tout le Shebang ensemble dans un seul fichier. Ils sont présents, mais ne sont pas exécutés/instanciés avant d'être nécessaires. Les améliorations en termes de vitesse et de bande passante que vous obtenez en procédant énormément l'emportent largement sur les améliorations supposées du téléchargement paresseux d'un contrôleur à 20 lignes particulier. En fait, le temps de latence réseau et le temps de transmission gaspillés pour ce contrôleur vont être d'un ordre de grandeur supérieur à la taille du contrôleur lui-même.

Mais disons que vous avez vraiment besoin de télécharger paresseux, peut-être pour des éléments de votre application peu utilisés, tels qu'une interface d'administration. C'est un cas très légitime. Require peut en effet le faire pour vous. Mais il y a aussiplusieursautres , potentiellement ​​ plussoupleoptions qui accomplissent la même chose. Et Angular 2.0 va apparemment s’occuper de cela pour nous, intégré au routeur . ( Détails .)

Mais qu'en est-il du développement sur ma boîte de dev locale?

Comment puis-je charger tous mes dizaines/centaines de fichiers de script sans avoir à les attacher tous manuellement à index.html?

Jetez un coup d'œil aux sous-générateurs dans générateur-angulaire de Yeoman, ou aux modèles d'automatisation incorporés dans générateur-gulp-angulaire , ou à l'automatisation Webpack standard pour React. Celles-ci vous offrent un moyen simple et évolutif pour: attacher automatiquement les fichiers au moment du scaffoldage des composants ou simplement les saisir automatiquement s'ils sont présents dans certains dossiers/correspondent à certains modèles globaux. Vous n'avez plus jamais besoin de penser à votre propre chargement de script une fois que vous avez les dernières options.

En bout de ligne?

Exiger est un excellent outil pour certaines choses. Mais allez avec le grain chaque fois que possible et séparez vos préoccupations chaque fois que possible. Laissez Angular s'inquiéter du propre modèle de modularisation d'Angular et envisagez d'utiliser les modules ES6 ou CommonJS comme modèle de modularisation général. Laissez les outils d'automatisation modernes s'inquiéter du chargement de script et de la gestion des dépendances. Et veillez à ce que le chargement paresseux soit asynchrone de manière granulaire, plutôt que de le mêler aux deux autres préoccupations.

Cela dit, si vous développez des applications Angular mais que vous ne pouvez pas installer Node sur votre machine pour utiliser les outils d'automatisation Javascript pour une raison quelconque, alors Require peut constituer une bonne solution alternative. Et j’ai vu des configurations très élaborées dans lesquelles les gens veulent charger dynamiquement des composants Angular qui déclarent chacun leurs propres dépendances ou quelque chose de ce genre. Et bien que j'essaierais probablement de résoudre ce problème d'une autre manière, je peux voir le bien-fondé de l'idée, dans cette situation très particulière.

Mais sinon ... en partant de zéro avec une nouvelle application Angular et la flexibilité nécessaire pour créer un environnement d'automatisation moderne ... vous disposez de nombreuses autres options, plus flexibles et plus modernes.

(Mis à jour à plusieurs reprises pour suivre l'évolution de la scène JS.)

151
XML

Oui, c'est logique.

Les modules angulaires n'essayent pas de résoudre le problème de l'ordre de chargement des scripts ou de l'extraction de scripts paresseux. Ces objectifs sont orthogonaux et les deux systèmes de modules peuvent coexister et atteindre leurs objectifs.

Source: site officiel de Angular JS

135
Tiago Reis

Je pense que ceci est une question subjective, donc je vais donner mon opinion subjective.

Angular intègre un mécanisme de modularisation. Lorsque vous créez votre application, la première chose à faire est de:

var app = angular.module("myApp");

puis

app.directive(...);

app.controller(...);

app.service(...);

Si vous jetez un coup d'œil à la graine angulaire qui est une application de démarrage ordonnée pour Angular, ils ont séparé les directives, les services, les contrôleurs, etc. en différents modules, puis chargé ces modules en tant que dépendances de votre application principale.

Quelque chose comme :

var app = angular.module("myApp",["Directives","Controllers","Services"];

Angular aussi paresseux charge ces modules (dans la mémoire) et non leurs fichiers de script.

Pour ce qui est du chargement paresseux des fichiers de script, être franc à moins que vous n'écriviez quelque chose d'extrêmement volumineux serait excessif, car angular réduit par sa nature même la quantité de code que vous écrivez. Une application typique écrite dans la plupart des autres cadres pourrait s’attendre à une réduction d’environ 30 à 50% du LOC si elle est écrite en angle.

57
ganaraj

Utiliser RequireJS avec AngularJS est logique, mais seulement si vous comprenez comment chacune d’elles fonctionne en ce qui concerne l’injection de dépendance , car bien que les deux injectent des dépendances, elles s’injectent de manière très différente. des choses.

AngularJS a son propre système de dépendance qui vous permet d’injecter des modules AngularJS à un module nouvellement créé afin de réutiliser des implémentations. Supposons que vous ayez créé un "premier" module qui implémente un filtre AngularJS "greet":

angular
  .module('first', [])
  .filter('greet', function() {
    return function(name) {
      return 'Hello, ' + name + '!';
    }
  });

Et maintenant, supposons que vous souhaitiez utiliser le filtre "saluer" dans un autre module appelé "second" qui implémente un filtre "au revoir". Vous pouvez faire cela en injectant le "premier" module au "deuxième" module:

angular
  .module('second', ['first'])
  .filter('goodbye', function() {
    return function(name) {
      return 'Good bye, ' + name + '!';
    }
  });

Pour que cela fonctionne correctement sans RequireJS, vous devez vous assurer que le "premier" module AngularJS est chargé sur la page avant de créer le "deuxième" module AngularJS. Citation de la documentation:

En fonction du module, cela signifie que le module requis doit être chargé avant le module requis.

En ce sens, RequireJS peut vous aider, car RequireJS fournit un moyen simple d’injecter des scripts dans la page et d’organiser les dépendances entre les scripts.

Pour revenir aux "premier" et "deuxième" modules AngularJS, voici comment vous pouvez le faire en utilisant RequireJS en séparant les modules sur différents fichiers pour exploiter les dépendances de script en cours de chargement:

// 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 + '!';
      }
    });
});

Vous pouvez voir que nous dépendons du fichier "firstModule" à injecter avant que le contenu du rappel RequireJS puisse être exécuté, ce qui nécessite le "premier" module AngularJS à charger pour créer le "second" module AngularJS.

Note secondaire: L'injection de "angular" sur les fichiers "firstModule" et "secondModule" en tant que dépendance est nécessaire pour pouvoir utiliser AngularJS dans la fonction de rappel RequireJS et le configurer dans RequireJS config pour mapper "angular" au code de bibliothèque. Vous pouvez également avoir chargé AngularJS sur la page de manière traditionnelle (balise de script) bien que les avantages de RequireJS soient annulés.

Plus de détails sur le support RequireJS de la version 2.0 du noyau AngularJS sur mon article de blog.

Basé sur mon article de blog "Donner un sens à RequireJS avec AngularJS" , voici le lien .

33
leog

Comme @ganaraj l'a mentionné, AngularJS repose essentiellement sur l'injection de dépendance. Lors de la création d'applications de semences jouets avec et sans RequireJS, j'ai personnellement constaté que RequireJS était probablement excessif dans la plupart des cas d'utilisation.

Cela ne veut pas dire que RequireJS n'est pas utile pour ses capacités de chargement de script et pour garder votre base de code propre pendant le développement. Combinaison de l'optimiseur r.js ( https://github.com/jrburke/r.js ) avec amande ( https://github.com/jrburke/almond ) peut créer une histoire de chargement de script très mince. Cependant, étant donné que ses fonctionnalités de gestion des dépendances ne sont pas aussi importantes avec angular au cœur de votre application, vous pouvez également évaluer l'autre côté client (HeadJS, LABjs, ...) ou même le côté serveur (MVC4 Bundler,. ..) solutions de chargement de script pour votre application particulière.

21
johlrich

Oui, spécialement pour les très grands SPA.

Dans certains cas, RequireJS est indispensable. Par exemple, je développe des applications PhoneGap en utilisant AngularJS qui utilise également Google Map API. Sans chargeur AMD tel que RequireJS, l'application se bloquerait simplement au lancement en mode hors connexion, car elle ne pourrait pas générer les scripts de l'API Google Map. Un chargeur AMD me permet d’afficher un message d’erreur à l’utilisateur.

Cependant, l'intégration entre AngularJS et RequireJS est un peu délicate. J'ai créé angularAMD pour rendre le processus moins pénible:

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

17
marcoseu

Réponse courte, c'est logique. Récemment, cela a été discuté dans ng-conf 2014. Voici la présentation sur ce sujet:

http://www.youtube.com/watch?v=4yulGISBF8w

12
Dalorzo

Il est judicieux d'utiliser requirejs avec angularjs si vous envisagez de charger paresseux des contrôleurs, des directives, etc. tout en combinant plusieurs dépendances paresseuses dans des fichiers de script uniques pour un chargement paresseux beaucoup plus rapide. RequireJS a un outil d'optimisation qui facilite la combinaison. Voir http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/

7
ify.io

Oui, il est logique d'utiliser requireJS avec Angular. J'ai passé plusieurs jours à tester plusieurs solutions techniques.

J'ai créé un Angular Seed avec RequireJS côté serveur. Très simple. J'utilise la notation SHIM pour aucun module AMD et non AMD car je pense qu'il est très difficile de traiter avec deux systèmes d'injection de dépendance différents.

J'utilise grunt et r.js pour concaténer des fichiers js sur le serveur dépend du fichier de configuration SHIM (dépendance). Donc, je ne renvoie qu'un seul fichier js dans mon application.

Pour plus d’informations, allez sur mon github Angular Seed: https://github.com/matohawk/angular-seed-requirejs

7
Matohawk

J'éviterais d'utiliser Require.js. Les applications que j'ai vues font disparaître de nombreux types d'architecture de modèle de module. AMD, Révéler, différentes versions de IIFE, etc. Il existe d’autres méthodes de chargement à la demande, telles que loadOnDemand Angular mod . L'ajout d'autres éléments remplit simplement votre code et crée un faible rapport signal sur bruit et rend votre code difficile à lire.

3

Voici l'approche que j'utilise: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-ver-very-large-applications/

La page présente une implémentation possible de AngularJS + RequireJS, dans laquelle le code est divisé par caractéristiques, puis par type de composant.

2
Avi Haiat

Réponse de Brian Ford

AngularJS a son propre système de modules et n'a généralement pas besoin de quelque chose comme RJS.

Référence: https://github.com/yeoman/generator-angular/issues/4

1
stevemao

Je pense que cela dépend de la complexité de votre projet puisque angular est assez modulaire. Vos contrôleurs peuvent être mappés et vous pouvez simplement importer ces classes JavaScript dans votre page index.html.

Mais au cas où votre projet s'agrandisse. Ou si vous anticipez un tel scénario, vous devriez intégrer angular avec requirejs. Dans this article, vous pouvez voir une application de démonstration pour une telle intégration.

0
lastboy