Ist es sinnvoll, Require.js mit Angular.js zu verwenden?

Ich bin ein Neuling zu Angular.js und versuche zu verstehen, wie es sich von Backbone.js unterscheidet … Wir haben die Abhängigkeiten unserer Pakete mit Require.js während der Verwendung von Backbone verwaltet. Macht es Sinn, das Gleiche mit Angular.js zu tun?

    Ja, es ist sinnvoll, angular.js zusammen mit require.js wobei Sie require.js zum Modularisieren von Komponenten verwenden können.

    Ich kann Sie auf ein Seed-Projekt verweisen, das both angular.js and require.js . Ich hoffe, das hilft!

    Um zu wiederholen, was ich denke, ist die Frage des OP wirklich:

    Wenn ich eine Anwendung hauptsächlich in Angular 1.x aufbaue und (implizit) in der Ära von Grunt / Gulp / Broccoli und Bower / NPM, und ich vielleicht ein paar zusätzliche Bibliotheksabhängigkeiten habe, muss Require klar, spezifisch hinzufügen Wert jenseits von dem, was ich bekomme, wenn ich Angular ohne Require benutze?

    Oder anders ausgedrückt:

    Msgstr “Benötigt vanille Angular das grundlegende angulare Komponentenladen effektiv zu verwalten, wenn ich andere Möglichkeiten habe, das grundlegende Laden von Skripten zu handhaben?

    Und ich glaube, die grundlegende Antwort darauf lautet: “Es sei denn, Sie haben etwas anderes vor und / oder Sie sind nicht in der Lage, neuere, modernere Werkzeuge zu verwenden.”

    Lassen Sie uns zu Beginn klar sein: RequireJS ist ein großartiges Werkzeug, das einige sehr wichtige Probleme getriggers hat und uns auf den Weg zu mehr skalierbaren, professionelleren Javascript-Anwendungen geführt hat. Es war das erste Mal, dass viele Menschen mit dem Konzept der Modularisierung konfrontiert wurden und Dinge aus der globalen Reichweite herausholten. Wenn Sie also eine Javascript-Anwendung erstellen möchten, die skaliert werden muss, sind Require und das AMD-Muster keine schlechten Werkzeuge dafür.

    Aber gibt es etwas Bestimmtes an Angular, das Require / AMD besonders gut macht? In der Tat bietet Ihnen Angular ein eigenes Modularisierungs- und Einkapselungsmuster, das die grundlegenden Modularisierungsfunktionen von AMD in mehrfacher Hinsicht überflüssig macht. Und die Integration von Angular-Modulen in das AMD-Muster ist nicht unmöglich, aber es ist ein bisschen … knifflig. Sie werden definitiv Zeit damit verbringen, die beiden Muster gut zu integrieren.

    Für einige Perspektiven aus dem Angular-Team selbst gibt es das von Brian Ford, Autor des Angular Batarang und jetzt Mitglied des Angular-coreteams:

    Ich empfehle nicht, RequireJS mit AngularJS zu verwenden. Obwohl es sicherlich möglich ist, habe ich keinen Fall gesehen, in dem RequireJS in der Praxis nützlich war.

    Also zu der sehr spezifischen Frage von AngularJS: Angular und Require / AMD sind orthogonal und stellenweise überlappend dar. Sie können sie zusammen verwenden, aber es gibt keinen Grund, der speziell auf die Natur / Muster von Angular selbst bezogen ist.

    Aber was ist mit der grundlegenden Verwaltung von internen und externen Abhängigkeiten für skalierbare Javascript-Anwendungen? Brauche ich nicht etwas wirklich Wichtiges für mich?

    Ich empfehle Bower und NPM und besonders NPM. Ich versuche nicht, einen heiligen Krieg über die komparativen Vorteile dieser Werkzeuge zu beginnen. Ich möchte nur sagen: Es gibt andere Möglichkeiten, diese Katze zu häuten, und diese Wege könnten sogar besser sein als AMD / Require. (Sie haben sicherlich eine viel populärere Dynamik Ende 2015, insbesondere NPM, kombiniert mit ES6- oder CommonJS-Modulen. Siehe zugehörige SO-Frage .)

    Was ist mit Lazy Loading?

    Beachten Sie, dass Lazy-Loading und Lazy-Download unterschiedlich sind. Angulars Lazy-Loading bedeutet nicht, dass du sie direkt vom Server ziehst. In einer Yeoman-ähnlichen Anwendung mit Javascript-Automatisierung verkettet und verkleinert man den gesamten Shebang zu einer einzigen Datei. Sie sind vorhanden, werden aber nicht ausgeführt / instanziiert, bis sie benötigt werden. Die Geschwindigkeits- und Bandbreitenverbesserungen, die Sie dadurch erreichen, überwiegen erheblich die angeblichen Verbesserungen durch das Herunterladen eines bestimmten 20-Zeilen-Controllers. In der Tat wird die Verschwendung von Netzwerklatenz und Übertragungsaufwand für diesen Controller um eine Größenordnung größer sein als die Größe des Controllers selbst.

    Aber nehmen wir an, Sie brauchen wirklich Lazy-Download, vielleicht für selten verwendete Teile Ihrer Anwendung, wie zum Beispiel eine Admin-Oberfläche. Das ist ein sehr legitimer Fall. Require kann das wirklich für dich tun. Aber es gibt auch viele andere , möglicherweise flexiblere Optionen , die das Gleiche erreichen. Und Angular 2.0 wird das für uns, eingebaut in den Router, scheinbar erledigen . ( Details .)

    Aber was ist bei der Entwicklung auf meinen lokalen Dev Boxen?

    Wie kann ich alle meine Dutzende / Hunderte von Skriptdateien laden, ohne sie alle manuell an index.html anhängen zu müssen?

    Werfen Sie einen Blick auf die Generatoren in Yeoman’s Generator-Angular oder auf die Automationsmuster in Generator-Gulp- Angular oder auf die Standard-Webpack-Automation für React. Diese bieten Ihnen eine saubere, skalierbare Möglichkeit, entweder die Dateien automatisch anzuhängen, wenn Komponenten gerüstet sind, oder sie einfach automatisch zu erfassen, wenn sie in bestimmten Ordnern vorhanden sind / bestimmten Glob-Mustern entsprechen. Sie müssen nie wieder über Ihr eigenes Skript-Laden nachdenken, sobald Sie die letzteren Optionen haben.

    Endeffekt?

    Require ist ein großartiges Werkzeug für bestimmte Dinge. Aber gehen Sie so weit wie möglich mit dem Getreide, und trennen Sie Ihre Sorgen wann immer möglich. Angular sollte sich über Angulars eigenes Modularisierungsmuster sorgen und ES6-Module oder CommonJS als allgemeines Modularisierungsmuster verwenden. Lassen Sie moderne Automatisierungswerkzeuge über das Laden von Skripten und die Verwaltung von Abhängigkeiten sorgen. Und sorge dafür, dass das asynchrone Lazy Loading granular erfolgt, anstatt es mit den anderen beiden Problemen zu verwechseln.

    Das heißt, wenn Sie Angular-Apps entwickeln, aber Node auf Ihrem Computer nicht installieren können, um Javascript-Automatisierungstools aus irgendeinem Grund zu verwenden, dann ist Require möglicherweise eine gute alternative Lösung. Und ich habe sehr aufwendige Setups gesehen, bei denen Angular-Komponenten dynamisch geladen werden sollen, die jeweils ihre eigenen Abhängigkeiten deklarieren. Und während ich wahrscheinlich versuchen würde, dieses Problem auf andere Weise zu lösen, kann ich die Vorzüge der Idee für diese besondere Situation erkennen.

    Aber ansonsten … wenn man von vorne mit einer neuen Angular-Anwendung beginnt und flexibel ist, um eine moderne Automatisierungsumgebung zu schaffen … dann gibt es viele andere, flexiblere und modernere Optionen.

    (Wird wiederholt aktualisiert, um mit der sich entwickelnden JS-Szene Schritt zu halten.)

    Ja, es macht Sinn.

    Eckige Module versuchen nicht, das Problem der Skript-Ladeordnung oder des Abrufs von faulen Skripten zu lösen. Diese Ziele sind orthogonal und beide Modulsysteme können Seite an Seite leben und ihre Ziele erfüllen.

    Quelle: Angular JS offizielle Website

    Dies ist meiner Meinung nach eine subjektive Frage, daher werde ich meine subjektive Meinung geben.

    Angular verfügt über einen eingebauten Modularisierungsmechanismus. Wenn Sie Ihre App erstellen, ist das erste, was Sie tun würden

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

    und dann

     app.directive(...); app.controller(...); app.service(...); 

    Wenn Sie sich die angular-seed ansehen, die eine ordentliche Starter-App für eckig ist, haben sie die Direktiven, Dienste, Controller usw. in verschiedene Module aufgeteilt und diese Module dann als Abhängigkeiten auf Ihrer Haupt-App geladen.

    Etwas wie :

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

    Angular lazy lädt diese Module (in den Speicher), nicht ihre Skriptdateien.

    In Bezug auf Lazy-Lade-Skript-Dateien, um ehrlich zu sein, es sei denn, Sie schreiben etwas extrem groß, wäre es ein Overkill, weil eckig von Natur aus die Menge an Code reduziert, den Sie schreiben. Eine typische App, die in den meisten anderen Frameworks geschrieben wurde, könnte eine Reduzierung von etwa 30-50% in LOC erwarten, wenn sie in eckig geschrieben wäre.

    Die Verwendung von RequireJS mit AngularJS ist sinnvoll, aber nur, wenn Sie verstehen, wie jeder von ihnen in Bezug auf die Abhängigkeitsinjektion funktioniert, denn obwohl beide Abhängigkeiten injizieren, injizieren sie sehr unterschiedliche Dinge.

    AngularJS verfügt über ein eigenes Abhängigkeitssystem, mit dem Sie AngularJS-Module in ein neu erstelltes Modul einspeisen können, um Implementierungen erneut zu verwenden. Angenommen, Sie haben ein “erstes” Modul erstellt, das einen AngularJS-Filter “greet” implementiert:

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

    Nehmen wir nun an, Sie möchten den “greet” -Filter in einem anderen Modul namens “second” verwenden, das einen “Goodbye” -Filter implementiert. Sie können das “erste” Modul in das “zweite” Modul einfügen:

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

    Um dies ohne RequireJS korrekt arbeiten zu können, müssen Sie sicherstellen, dass das “erste” AngularJS-Modul auf der Seite geladen ist, bevor Sie das “zweite” AngularJS-Modul erstellen. Zitat Dokumentation:

    Abhängig von einem Modul bedeutet, dass das erforderliche Modul geladen werden muss, bevor das anfordernde Modul geladen wird.

    In diesem Sinne kann RequireJS Ihnen hier helfen, da RequireJS eine saubere Möglichkeit bietet, Skripte auf die Seite zu injizieren, die Ihnen helfen, Skriptabhängigkeiten untereinander zu organisieren.

    Gehen wir zurück zu den “ersten” und “zweiten” AngularJS-Modulen. Hier ist, wie Sie es mit RequireJS tun können, indem Sie die Module auf verschiedene Dateien aufteilen, um das Laden von Skriptabhängigkeiten zu beschleunigen:

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

    Sie können sehen, dass wir von der “firstModule” -Datei abhängig sind, die injiziert werden soll, bevor der Inhalt des RequireJS-Callbacks ausgeführt werden kann, der das “erste” AngularJS-Modul benötigt, um das “zweite” AngularJS-Modul zu laden.

    Randnotiz: Das Einfügen von “angular” in die Dateien “firstModule” und “secondModule” als Abhängigkeit ist erforderlich, um AngularJS innerhalb der RequireJS-Callback-function zu verwenden, und es muss in RequireJS config konfiguriert werden, um “angular” dem Bibliothekscode zuzuordnen. Sie können AngularJS auch auf eine traditionelle Art und Weise auf die Seite laden (Skript-Tag), obwohl RequireJS davon profitiert.

    Weitere Details zu RequireJS Unterstützung von AngularJS Core von 2.0 Version auf meinem Blog-Post.

    Basierend auf meinem Blogbeitrag “Sinn von RequireJS mit AngularJS” , hier ist der Link .

    Als @ganaraj erwähnt AngularJS hat Abhängigkeitsinjektion in seinem core. Beim Erstellen von Spielzeugsaatanwendungen mit und ohne RequireJS fand ich persönlich, dass RequireJS für die meisten Anwendungsfälle wahrscheinlich übertrieben war.

    Das bedeutet nicht, dass RequireJS nicht nützlich ist, um Skripts zu laden und die Codebase während der Entwicklung sauber zu halten. Die Kombination des r.js-Optimierers ( https://github.com/jrburke/r.js ) mit Mandeln ( https://github.com/jrburke/almond ) kann eine sehr schlanke Story zum Laden von Skripten erstellen. Da die functionen zur Abhängigkeitsverwaltung jedoch nicht so wichtig für eckige Anwendungen sind, können Sie auch andere Client-Seiten (HeadJS, LABjs, …) oder sogar serverseitige (MVC4 Bundler, …) Lösungen zum Laden von Skripten auswerten für Ihre spezielle Anwendung.

    Ja, speziell für sehr große SPA.

    In einigen Szenarien ist RequireJS ein Muss. Zum Beispiel entwickle ich PhoneGap-Anwendungen mit AngularJS, die auch Google Map API verwenden. Ohne AMD Loader wie RequireJS würde die App beim Start einfach abstürzen, wenn sie offline ist, da sie die Google Map API-Skripte nicht erhalten kann. Ein AMD Loader gibt mir die Möglichkeit, dem Benutzer eine Fehlermeldung anzuzeigen.

    Die Integration zwischen AngularJS und RequireJS gestaltet sich jedoch etwas schwierig. Ich habe angularAMD erstellt, um dies zu einem weniger schmerzhaften process zu machen:

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

    Kurze Antwort ist, es macht Sinn. Vor kurzem wurde dies in ng-conf 2014 diskutiert. Hier ist der Vortrag zu diesem Thema:

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

    Es macht Sinn, requirejs mit angularjs zu verwenden, wenn Sie auf Lazy-Lade-Controllern und Direktiven usw. planen, während Sie auch mehrere träge Abhängigkeiten in einzelne Skriptdateien für viel schnelleres Lazy Loading kombinieren. RequireJS hat ein Optimierungs-Tool , das das Kombinieren einfach macht. Siehe http://ify.io/using-requirejs-with-optimization-for-lazy-loading-angularjs-artefacts/

    Ja, es macht Sinn, requireJS mit Angular zu verwenden, ich habe mehrere Tage damit verbracht, verschiedene technische Lösungen zu testen.

    Ich habe einen Angular Seed mit RequireJS auf der Serverseite erstellt. Sehr einfach. Ich verwende SHIM-Notation für kein AMD-Modul und nicht für AMD, weil ich denke, dass es sehr schwierig ist, mit zwei verschiedenen Dependency-Injection-Systemen umzugehen.

    Ich verwende grunt und r.js, um js-Dateien auf dem Server zu verketten, hängt von der SHIM-Konfigurationsdatei (Abhängigkeitsdatei) ab. Also verweise ich nur eine js-Datei in meiner App.

    Für weitere Informationen gehen Sie auf meine Github Angular Seed: https://github.com/matohawk/angular-seed-requirejs

    Ich würde vermeiden Require.js zu verwenden. Apps, die ich gesehen habe, führen dazu, dass mehrere Arten von Modulmusterarchitekturen durcheinander gebracht werden. AMD, Revealing, verschiedene Varianten von IIFE, etc. Es gibt andere Möglichkeiten, auf Nachfrage wie der LoadOnDemand Angular Mod zu laden. Das Hinzufügen von anderem Zeug füllt nur Ihren Code voll von Cruft und erzeugt ein niedriges Signal-Rausch-Verhältnis und macht Ihren Code schwer zu lesen.

    Hier ist der Ansatz, den ich verwende: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-yy-large-applications/

    Die Seite zeigt eine mögliche Implementierung von AngularJS + RequireJS, wobei der Code nach Features und dann nach Komponententyp aufgeteilt wird.

    Antwort von Brian Ford

    AngularJS hat ein eigenes Modulsystem und benötigt normalerweise nicht so etwas wie RJS.

    Referenz: https://github.com/yeoman/generator-angular/issues/40

    Ich denke, das hängt von Ihrer Projektkomplexität ab, da eckig ziemlich modularisiert ist. Ihre Controller können zugeordnet werden und Sie können diese JavaScript-classn einfach in Ihre index.html-Seite importieren.

    Aber für den Fall, dass Ihr Projekt größer wird. Oder Sie antizipieren ein solches Szenario, sollten Sie angular mit requires integrieren. In diesem Artikel können Sie eine Demo-App für diese Integration sehen.