-Code-Organisation in Groß AngularJS und JavaScript-Anwendungen
Viele Entwickler kämpfen mit, wie eine Anwendung Code Basis zu organisieren, sobald es in der Größe wächst. Ich habe dies kürzlich in AngularJS und JavaScript-Anwendungen gesehen, aber in der Vergangenheit war es ein Problem über alle Technologien einschließlich vieler Java-und Flex-Apps, die ich in der Vergangenheit gearbeitet habe.
Der allgemeine Trend ist eine Besessenheit, Dinge nach Typ zu organisieren. Es trägt eine frappierende Ähnlichkeit mit der Art und Weise, wie Menschen ihre Kleidung organisieren .
Piles auf dem Boden
Lassen Sie uns in Winkel-Samen einen Blick darauf werfen, den offiziellen Startpunkt für AngularJS Apps. Die "App" enthält die folgende Struktur:
css/img/js/app.js controllers.js directives.js filters.js services.js lib/partials/Die JavaScript-Verzeichnis hat eine Datei für jede Art von Objekt schreiben wir. Dies ist ähnlich wie Ihre Kleidung in verschiedene Stapel auf dem Boden zu organisieren. Sie haben einen Haufen Socken, Unterwäsche, Hemden, Hosen, etc. Sie wissen, dass Ihre schwarzen Wollsocken sind in Stapel in der Ecke, aber es wird eine Weile dauern, um sie zu graben heraus.
Dies ist ein Durcheinander. Leute sollten nicht so leben und Entwickler sollten nicht so kodieren. Sobald Sie über ein halbes Dutzend oder so Controller oder Dienstleistungen diese Dateien werden unhandlich sind: Objekte Sie suchen sind schwer zu finden, werden Datei Changesets in der Quellcodeverwaltung opak, usw.
Die Sockenschublade
Der nächste logische Durchlauf beim Organisieren von JavaScript umfasst das Erstellen eines Verzeichnisses für einige der Archetypen und das Aufteilen von Objekten in ihre eigenen Dateien . Um die Metapher der Kleidung fortzusetzen, haben wir jetzt in eine nette Mohaghony-Kommode investiert und planen, Socken in eine Schublade zu stecken, Unterwäsche in eine andere, und ordentlich unsere Hosen und Hemden in noch andere falten.
Stellen wir uns vor, wir bauen eine einfache E-Commerce-Website mit einem Login Flow, Produktkatalog und Einkaufswagen UIs. Wir haben außerdem neue Archetypen für Modelle (Geschäftslogik und -status) und Dienste (Proxies für HTTP/JSON-Endpunkte) definiert, anstatt sie in Angulars einzigem "Service" -Datentyp zu integrieren. Unser JavaScript Verzeichnis kann nun wie folgt aussehen:
Controller/LoginController.js RegistrationController.js ProductDetailController.js SearchResultsController.js directives.js filters.js models/CartModel.js ProductModel.js SearchResultsModel.js UserModel.js Dienstleistungen/CartService.js UserService.js ProductService.js Nizza! Objekte können jetzt einfach durch Durchsuchen der Dateistruktur oder mit IDE-Verknüpfungen, Änderungssets in der Versionskontrolle jetzt deutlich angezeigt werden, was wurde geändert, etc.Dies ist eine große Verbesserung, leidet aber immer noch unter einigen Einschränkungen.
Stellen Sie sich vor, Sie sind im Büro und erkennen, dass Sie ein paar Outfits brauchen für eine Geschäftsreise morgen früh gereinigt. Sie rufen zu Hause an und fragen Sie Ihren Lebensgefährten, Ihre schwarzen Holzkohle und blauen Nadelstreifenanzüge zu den Reinigern zu nehmen. Und vergessen Sie nicht das graue Hemd mit die schwarze Paisley-Krawatte und das weiße Hemd mit der festen gelben Krawatte. Stellen Sie sich vor, dass Ihr Lebensgefährte mit der Ihrer Kommode und Garderobe völlig unvertraut ist. Während sie sich durch Ihre Krawattenschublade bewegen, sehen sie drei gelbe Krawatten. Welchen zu wählen?
Wäre es nicht schön, wenn Ihre Kleidung nach Outfit organisiert wäre? Während gibt es praktische Einschränkungen wie Kosten und Platz, die diese mit Kleidung in der realen Welt schwierig machen, kann etwas ähnliches mitCode ohne Kosten getan werden.
Modularer Aufbau
Hoffentlich wird die banalen Metaphern nicht zu langweilig gewesen, aber hier sind die rekapituliert:
Ihre bedeutend andere ist der neue Entwickler im Team, die gefragt gewesen ein Fehler auf einen beheben die vielen Bildschirme in deiner App Der Entwickler durchsucht die Verzeichnisstruktur und sieht alle Controller, Modelle und Services übersichtlich geordnet vor. Leider teilt es ihm nichts darüber mit, welche Objekte verwandt sind oder Abhängigkeiten voneinander haben. Wenn der Entwickler an einem Punkt einen Teil des Codes wiederverwenden möchte, müssen sie Dateien aus einer Reihe von verschiedenen Ordnern sammeln und wird Code aus einem anderen Ordner immer woanders vergessen. Ob Sie es glauben oder nicht, Sie müssen selten alle der Controller aus der E-Commerce-App in der neuen Reporting-App , die Sie erstellen, wiederverwenden. Möglicherweise müssen Sie jedoch einige der Authentifizierungslogik erneut verwenden. Wäre es nicht schön, wenn das alles in einem Platz wäre? Lassen Sie uns die App reorganisieren basierend auf Funktionsbereiche:
Warenkorb/CartModel.js CartService.js common/directives.js filters.js Produkt/Suche/SearchResultsController.js SearchResultsModel.js ProductDetailController.js ProductModel.js ProductService.js user/ LoginController.js RegistrationController.js UserModel.js UserService.js Jeder beliebige Entwickler kann nun den obersten Ordner öffnen und sofort Einblick in die Anwendung erhalten. Objekte im selben Ordner haben eine Beziehung und einige haben Abhängigkeiten auf anderen. Zu verstehen, wie der Anmelde- und Registrierungsprozess funktioniert ist so einfach wie das Durchsuchen der Dateien in diesem Ordner. Primitive Wiederverwendung über Copy/Paste kann mindestens durch Kopieren des Ordners in ein anderes Projekt erreicht werden.
Mit AngularJS können wir dies einen Schritt weiter und ein Modul von diesen zugehörigen Code erstellen:
1 2 3 4 5 6 7 8 9 10 11 12 13 var userModule = angular.module ('userModule ', []); userModule.factory ('userService', ['$ http', Funktion ($ http) {return new UserService ($ http);}]);
userModule.factory ('userModel', ['userService', function (userService) {neues UserModel (userService);}]);
userModule.controller ('loginController', ['$ scope', 'userModel', LoginController]); userModule.controller ('registrationController', ['$ scope', 'userModel', RegistrationController]); view rawUserModule.js gehostet mit ❤ von GitHub Wenn wir dann UserModule.js in den Benutzerordner platzieren, wird es zu einem "Manifest" der Objekte, die in diesem Modul verwendet werden. Dies wäre auch ein sinnvoller Platz um einige Loader-Direktiven für RequireJS oder Browserify hinzuzufügen.
Tipps für Common Code
Jede Anwendung haben gemeinsamen Code, der von vielen Modulen verwendet wird. Wir brauchen nur einen Platz dafür, der ein Ordner namens "common" oder "shared" oder was auch immer Sie mögen. In wirklich großen Anwendungen tendiert man dazu, eine Überlappung von Funktionalität und übergreifenden Bedenken zu haben. Dies kann durch einige Techniken überschaubar gemacht werden:
Wenn die Objekte Ihres Moduls direkten Zugriff auf mehrere "gemeinsame" Objekte benötigen, schreiben Sie eine oder mehrere Fassaden für sie. Dies kann dazu beitragen, die Anzahl der Kollaborateure für jedes Objekt zu reduzieren, da es zu viele Kollaborateure gibt. Wenn Ihr "gemeinsames" Modul groß wird, unterteilen Sie es in Submodule, die einen bestimmten Funktionsbereich oder ein Problem betreffen. Stellen Sie sicher, dass Ihre Anwendungsmodule nur die "gemeinsamen" Module verwenden, die sie benötigen. Dies ist eine Variante des "Interface Trennprinzips" von SOLID. Fügen Sie Hilfsmethoden zu $ rootScope hinzu, damit sie von untergeordneten Bereichen verwendet werden können. Dies kann dazu beitragen, zu verhindern, dass die gleiche Abhängigkeit (z. B. "PermissionsModel") in jeden Controller in der Anwendung verdrahten muss. Beachten Sie, dass dies sparsam durchgeführt werden sollte , um zu vermeiden, den globalen Geltungsbereich zu überlasten und Abhängigkeiten nicht offensichtlich zu machen. Verwenden Sie Ereignisse, um zwei Komponenten zu entkoppeln, die keinen expliziten Verweis auf einander benötigen. AngularJS ermöglicht dies über die Methoden $ emit, $ broadcast und $ on für das Scope-Objekt. Ein Controller kann ein Ereignis auslösen, um eine Aktion auszuführen, und dann eine Benachrichtigung erhalten, dass die Aktion abgeschlossen wurde. Schnelle Anmerkung über Anlagen und Tests
Ich denke, es gibt mehr Spielraum für die Organisation von HTML, CSS und Bilder. Platzieren sie in einem "Assets" Unterordner des Moduls wahrscheinlich die beste Balance zwischen Kapselung der Asset-Abhängigkeiten des Moduls und nicht zu viel Dinge überladen. Allerdings denke ich, ein separater Top-Level-Ordner für diesen Inhalt, der enthält eine Ordnerstruktur, die die Paketstruktur der App spiegelt auch vernünftig ist. Ich denke, es funktioniert auch gut für Tests.
Ich denke, das vollständige Beispiel ist hier http://ify.io/using-requirejs-with-optimization-for-lazy-loading-angularjs-artefacts/ – Shohel
Dank Shohel, wir haben die Lazy-loading behandelt. Meine Zweifel bestehen eher darin, wie man eine skalierbare Anwendung entwerfen kann, mit mehr als 20 Entwicklern kann die minimale Abhängigkeit funktionieren. Und wie man all das Feature mit einigen definierten Konventionen zusammenbringt. Versuch zu zeichnen und Architekturdiagramm. – Anandh
Kein Problem. Sie arbeiten nur mit ihrer seitenweisen Javascript-Datei, wie Controller, Service und Direktive, Sie müssen einen gemeinsamen Service, Factory erstellen. – Shohel