Est-il judicieux d'utiliser Require.js avec Angular.js? [fermé]

443

Je suis un débutant à Angular.js et j'essaie de comprendre en quoi il diffère de Backbone.js ... Nous avions l'habitude de gérer nos dépendances de packages avec Require.js tout en utilisant Backbone. Est-il judicieux de faire de même avec Angular.js?

Franck
la source
Un autre blog et projet de démarrage: startersquad.com/blog/angularjs-requirejs
iwein
19
Non - N'utilisez pas require.js OU naviguez avec Angular.JS il n'y a tout simplement pas besoin de le faire - AngularJS a un système de modules et l'utilisation d'un autre système de modules au-dessus vous rendra la vie inutilement difficile. J'ai suivi les réponses dans ce fil et perdu trop d'heures sur quelque chose qui était complètement inutile. Veuillez lire cet article qui explique pourquoi: medium.com/@dickeyxxx/…
VitalyB
Lisez ceci pour comprendre la différence entre les modules angulaire et requis juristr.com/blog/2014/07/lazy-angular-modules
pilavdzice
1
voici une excellente vidéo qui explique pourquoi c'est une bonne idée et montre comment utiliser requireJS avec angularJS youtube.com/watch?v=4yulGISBF8w#t=142
gskalinskii
2
@VitalyB Nice article! Je préfère charger des applications en petits morceaux. Cela ne coûtera rien assez tôt . Heck, cela ne coûte rien pour moi en ce moment.
dsign

Réponses:

224

Oui, il est logique d'utiliser angular.jsavec require.jslequel vous pouvez utiliserrequire.js pour la modularisation des composants.

Il existe un projet d'amorçage qui utilise both angular.js and require.js.

Anshu
la source
108
Le projet de graine mentionné ci-dessus n'a pas été touché depuis un an, donc j'en ai créé un nouveau en utilisant les dernières AngularJS et RequireJS avec un support complet pour les tests pilotés par les tests.
tnajdek
2
@tnajdek, j'ai mis à jour le lien dans la réponse d'Anshu pour pointer vers celui que vous proposez.
David Rivers
7
Notez qu'aucun de ces projets d'amorçage n'est approuvé par l'équipe Angular. Exiger est un modèle qui avait plus de sens dans d'autres contextes, et le chausser en angulaire n'est pas, à mon humble avis, une meilleure pratique.
XML
2
Le livre O'Reilly AngularJS de Brad Green & Shyam Seshadri (publié en avril de cette année) recommande également d'ajouter RequireJS au début de la croissance d'un projet Angular, et expose les détails assez clairement.
bjorke
1
Je préfère de loin tout faire au moment de la construction 1. browserify.org 2. npmjs.org/package/gulp-angular-filesort
A-Dubb
150

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

Si je crée une application principalement dans Angular 1.x, et (implicitement) à l'ère de Grunt / Gulp / Broccoli et Bower / NPM, et que j'ai peut-être quelques dépendances de bibliothèque supplémentaires, faut-il ajouter clair, spécifique valeur au-delà de ce que j'obtiens en utilisant Angular sans exiger?

Ou, autrement dit:

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

Et je crois que la réponse de base à cela est: "pas à moins que vous ayez quelque chose d'autre en cours et / ou que vous ne puissiez pas utiliser des outils plus récents et plus modernes."

Soyons clairs au début: RequireJS est un excellent outil qui a résolu des problèmes très importants et nous a lancé sur la voie que nous suivons, vers des applications Javascript plus évolutives et plus professionnelles. Surtout, c'était la première fois que de nombreuses personnes rencontraient le concept de modularisation et de sortir les choses de la portée mondiale. Donc, si vous allez 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, y a-t-il quelque chose de particulier dans Angular qui fait de Require / AMD un ajustement particulièrement bon?Non. En fait, Angular vous propose son propre modèle de modularisation et d'encapsulation, qui à bien des égards rend redondantes les fonctionnalités de modularisation de base d'AMD. Et, l'intégration de modules angulaires dans le modèle AMD n'est pas impossible, mais c'est un peu ... capricieux. Vous passerez certainement du temps à bien intégrer les deux modèles.

Pour une certaine perspective de l'équipe Angular elle-même, il y a ceci , de Brian Ford, auteur de l'Angular Batarang et maintenant membre de l'équipe de base Angular:

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

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

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

Je recommande de consulter Bower et NPM, et en particulier NPM. Je n'essaie pas de déclencher une guerre sainte au sujet des avantages comparatifs de ces outils. Je veux simplement dire: il existe d'autres façons d'écorcher ce chat, et ces façons peuvent être encore meilleures que AMD / Require. (Ils ont certainement un élan beaucoup plus populaire fin 2015, en particulier NPM, combiné avec des modules ES6 ou CommonJS. Voir la question SO connexe .)

Et le chargement paresseux?

Notez que le chargement différé et le téléchargement différé sont différents. Le chargement paresseux d'Angular ne signifie pas que vous les tirez directement du serveur. Dans une application de style Yeoman avec automatisation javascript, vous concaténez et réduisez l'ensemble du shebang ensemble dans un seul fichier. Ils sont présents, mais pas exécutés / instanciés jusqu'à ce qu'ils soient nécessaires. Les améliorations de la vitesse et de la bande passante que vous obtenez en faisant cela dépassent largement les améliorations alléguées du téléchargement paresseux d'un contrôleur 20 lignes particulier. En fait, la latence du réseau gaspillée et la surcharge de transmission 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 d'un téléchargement paresseux, peut-être pour des éléments de votre application rarement utilisés, comme une interface d'administration. C'est un cas très légitime. Exiger peut en effet le faire pour vous. Mais il existe également de nombreuses autres options , potentiellement plus flexibles , qui accomplissent la même chose. Et Angular 2.0 s'en occupera apparemment pour nous, intégré au routeur . ( Détails .)

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

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

Jetez un œil aux sous-générateurs dans le générateur angulaire de Yeoman, ou aux modèles d'automatisation incorporés dans le générateur-gulp-angulaire , ou à l'automatisation Webpack standard pour React. Ceux-ci vous offrent un moyen propre et évolutif de: attacher automatiquement les fichiers au moment où les composants sont échafaudés, ou simplement les saisir tous automatiquement s'ils sont présents dans certains dossiers / correspondre à certains modèles globaux. Vous n'aurez plus jamais besoin de penser à votre propre chargement de script une fois que vous aurez ces 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 autant que possible. Laissez Angular s'inquiéter du modèle de modularisation d'Angular et envisagez d'utiliser des modules ES6 ou CommonJS comme modèle de modularisation général. Laissez les outils d'automatisation modernes s'inquiéter du chargement des scripts et de la gestion des dépendances. Et prenez soin du chargement différé asynchrone de manière granulaire, plutôt qu'en le mêlant aux deux autres préoccupations.

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

Mais sinon ... en partant de zéro avec une nouvelle application angulaire et la flexibilité de créer un environnement d'automatisation moderne ... vous avez beaucoup d'autres options plus flexibles et plus modernes.

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

XML
la source
1
Le projet de démarrage NG-Boilerplate ( github.com/ngbp/ngbp ) crée également une webapp d'une seule page avec un fichier js. L'utilisation d'un manifeste HTML5 garantit que ce fichier n'est chargé qu'une seule fois par version.
Federico Elles
2
Bien que, comme toujours, <i> cela dépend </i>. De nombreuses personnes utilisent Require pour l'ensemble de leur architecture et doivent intégrer Angular dans cet écosystème. C'est une situation très différente que lorsque vous créez des applications isolément.
Dave Nichol
2
D'accord. Mais la poussée de l'OP semble être: "Si je construis une application principalement dans Angular, et (implicitement) le fait à l'ère de Grunt, et j'ai peut-être quelques dépendances de bibliothèque supplémentaires, nécessite-t-il d'ajouter une valeur claire et spécifique au-delà ce que j'obtiens en utilisant Angular sans exiger? " Et je crois que la réponse est: non. Si vous avez une énorme application avec 40 dépendances extérieures, ou si vous ne pouvez pas contrôler votre environnement CI, ou votre patron adore Require, ou vous adorez Require, ou Angular n'est qu'une partie d'une application plus grande, etc., etc., alors YMMV.
XML
1
Mais comme il ne semble pas poser ces questions, et comme il mentionne simplement le contexte alternatif d'une application Backbone, il semble demander: "vanilla Angular a-t-il besoin de Gérer efficacement ses composants?" Et la réponse est: "pas sauf si vous avez quelque chose d'autre en cours." En outre, cette question est venue à l'aube du mouvement Javascript CI, dans lequel nous avons obtenu de bien meilleures façons de gérer le «chargement de script» physique de base. Si ce problème est résolu, Require concerne essentiellement la correspondance des dépendances et l'encapsulation. Angular fait ces deux choses pour vous.
XML
Google utilise le chargement paresseux dans certains de ses projets AngularJS, car sinon, l'utilisateur téléchargerait 24 Mo de fichiers lors du premier chargement de la page (et cela avec des fichiers uglifiés et concaténés). Donc oui, dans les applications complexes, il ne suffit pas de concaténer toutes les sections, lorsqu'il y a des sections que l'utilisateur n'ouvrira pas à chaque visite.
ngDeveloper
136

Oui, c'est logique.

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

Source: site officiel d'Angular JS

Tiago Reis
la source
6
Si vous utilisez un module par fichier js, vous pouvez charger votre module angulaire sur n'importe quelle commande. Mais si vous voulez mettre par exemple différents services dans différents fichiers js mais que vous voulez les attacher sur le même module angulaire, vous devez charger la déclaration du module avant la déclaration des services. Il s'agit donc d'une décision d'architecture.
Matohawk
@Tiago: veuillez fournir un lien vers l'emplacement d'où vous l'avez obtenu. Je ne peux le trouver nul part. Je suppose que cela provenait d'une version antérieure des documents Angular, avant que les modèles d'Angular ne soient aussi bien établis, et avant qu'il ne soit devenu clair qu'il y avait des avantages significatifs à éviter Require, au moins pour les composants Angular.
XML
@XMLilley: pouvez-vous fournir un lien qui explique les avantages d'éviter Eviter lorsque vous utilisez Angular? Je décide d'utiliser ou non Require dans mon projet et cela semble utile.
Trevor
1
Je n'étais pas clair dans ma langue ici: il y a des avantages significatifs à tirer parti des propres chargeurs de modules intégrés d'Angular, et à aller avec le grain des modèles angulaires. La question n'est pas de savoir s'il faut éviter Require, mais plutôt s'il est utile d'ajouter une couche supplémentaire de complexité. Ce qui est clair, c'est que les modèles intégrés d'Angular répondront de manière pratique et élégante au besoin de charger les propres modules d'Angular. Si Require sert à charger des modules en dehors du contexte angulaire, qu'il en soit ainsi. Mais utiliser Require for Angular est superflu.
XML
6
@XMLilley Angular ne fait que vous injecter une dépendance. Le chargement réel du module est à votre charge. Vous pouvez le faire en ajoutant une balise de script, en ayant un script de génération ou en utilisant requirejs. Le système de module angulaire n'a aucune opinion à ce sujet.
gillesruppert
57

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

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

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

et alors

app.directive(...);

app.controller(...);

app.service(...);

Si vous regardez la graine angulaire qui est une application de démarrage soigné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 charge également paresseusement ces modules (en mémoire) et non leurs fichiers de script.

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

ganaraj
la source
5
En effet, il vaut mieux configurer les services dans Angular.js que charger les modules avec Require.js. Cela rend plus facile de jouer avec la portée et les services $, comme j'ai joué avec Socket.io
Marco Godínez
33

L'utilisation de RequireJS avec AngularJS est logique, mais uniquement si vous comprenez comment chacun d'eux fonctionne en ce qui concerne l' injection de dépendance , car bien que les deux injectent des dépendances, ils injectent des choses très différentes.

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

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

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

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

Le fait est que 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:

Selon un module, cela signifie que le module requis doit être chargé avant le chargement du module requis.

Dans ce sens, voici où RequireJS peut vous aider car RequireJS fournit un moyen propre d'injecter des scripts dans la page pour vous aider à organiser les dépendances de script entre eux.

Pour en 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 tirer parti du chargement des dépendances de script:

// 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 chargement du "premier" module AngularJS pour créer le "deuxième" module AngularJS.

Note latérale: L'injection de "angulaire" sur les fichiers "firstModule" et "secondModule" en tant que dépendance est requise afin d'utiliser AngularJS à l'intérieur de la fonction de rappel RequireJS et elle doit être configurée sur la configuration RequireJS pour mapper "angular" au code de bibliothèque. Vous pouvez également avoir AngularJS chargé sur la page de manière traditionnelle (balise de script) bien que défait les avantages RequireJS.

Plus de détails sur la prise en charge RequireJS du noyau AngularJS à partir de la version 2.0 sur mon blog.

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

leog
la source
2
Il est préférable, en incluant un lien, de résumer le contenu du lien ici sur Stack Overflow. Si votre lien venait à se rompre, ce que font les liens sur Internet, votre réponse ici serait inutile aux futurs visiteurs. Envisagez une modification pour apporter un résumé et améliorer ce post. Bonne chance!
jmort253
3
Voilà, merci jmort253.
leog
Merci d'avoir apporté ces modifications et expliqué comment RequireJS peut aider à gérer les dépendances pour éviter les problèmes avec Angular essayant de charger quelque chose qui n'existe pas encore.
jmort253
Je suis totalement d'accord, il est préférable d'utiliser cette approche pour les grandes applications, sinon vous aurez plusieurs balises <script> dans votre application.
I.Tyger
21

Comme @ganaraj l'a mentionné, AngularJS a l'injection de dépendances à sa base. Lors de la création d'applications de semences de jouets avec et sans RequireJS, j'ai personnellement trouvé que RequireJS était probablement excessif pour la plupart des cas d'utilisation.

Cela ne signifie pas 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. La combinaison de l'optimiseur r.js ( https://github.com/jrburke/r.js ) avec de l'amande ( https://github.com/jrburke/almond ) peut créer une histoire de chargement de script très mince. Cependant, comme 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 d'autres solutions de chargement de script côté client (HeadJS, LABjs, ...) ou même côté serveur (MVC4 Bundler, ...) pour votre application particulière.

johlrich
la source
17

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

Dans certains scénarios, RequireJS est un must. Par exemple, je développe des applications PhoneGap en utilisant AngularJS qui utilise également l'API Google Map. Sans chargeur AMD comme RequireJS, l'application se bloquerait simplement lors du lancement lorsqu'elle est hors ligne, car elle ne peut pas source les scripts API Google Map. Un chargeur AMD me donne la possibilité 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 ce processus moins douloureux:

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

marcoseu
la source
7

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

J'ai fait une graine angulaire 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 gérer deux systèmes d'injection de dépendances 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). Je ne fais donc référence qu'à un seul fichier js dans mon application.

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

Matohawk
la source
3

J'éviterais d'utiliser Require.js. Les applications que j'ai vues font cela gâcher plusieurs types d'architecture de modèle de module. AMD, Revealing, différentes versions de IIFE, etc. Il existe d'autres façons de charger à la demande comme le mod angulaire loadOnDemand . L'ajout d'autres éléments remplit simplement votre code de corruption, crée un faible rapport signal / bruit et rend votre code difficile à lire.

Julia Anne Jacobs
la source
0

Je pense que cela dépend de la complexité de votre projet car angulaire est à peu près 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 deviendrait plus grand. Ou si vous prévoyez un tel scénario, vous devez intégrer angular avec requirejs. Dans cet article, vous pouvez voir une application de démonstration pour une telle intégration.

lastboy
la source