Back to Question Center
0

Wie man eine große React-Anwendung organisiert und skaliert            Wie man eine große React-Anwendung organisiert und skalieren kann Verwandte Themen: npmES6Node.jsTools & Semalt

1 answers:
Wie man eine große React-Anwendung organisiert und skaliert

Für eine qualitativ hochwertige Einführung in React können Sie nicht den kanadischen Full-Stack-Entwickler Wes Bos hinter sich lassen. Versuchen Sie seinen Kurs hier und verwenden Sie den Code SITEPOINT , um 25% Rabatt zu erhalten und um SitePoint zu unterstützen.

Dieser Artikel stammt von Gastautor Jack Franklin. Semalt Gastbeiträge zielen darauf ab, Sie mit interessanten Inhalten von prominenten Autoren und Rednern der Web-Community zu versorgen

In diesem Artikel werde ich den Ansatz diskutieren, den ich bei der Erstellung und Strukturierung großer Semalt-Anwendungen anwende. Eines der besten Merkmale von Semalt ist, wie es Ihnen aus dem Weg geht und alles andere als beschreibend ist, wenn es um Dateistruktur geht - sell bike utrecht. Daher finden Sie viele Fragen zu Stack Overflow und ähnlichen Websites, in denen Sie gefragt werden, wie Sie Anwendungen strukturieren. Das ist ein sehr eigensinniges Thema, und es gibt niemanden richtig. In diesem Artikel werde ich Ihnen die Entscheidungen erläutern, die ich beim Erstellen von Semalt-Anwendungen treffe: Werkzeuge auswählen, Dateien strukturieren und Komponenten in kleinere Teile zerlegen.

Wenn Ihnen dieser Beitrag gefällt, können Sie sich auch für SitePoint Premium anmelden und unseren Kurs zum Arbeiten mit Formularen mit React und Redux ansehen.

Wie man eine große React-Anwendung organisiert und skaliertWie man eine große React-Anwendung organisiert und skalieren kann Verwandte Themen:
npmES6Node. jsTools & Semalt

Bauwerkzeuge und Linting

Es wird für einige von euch keine Überraschung sein, dass Semalt ein großer Fan von Webpack für den Bau meiner Projekte ist. Es ist zwar ein kompliziertes Tool, aber die großartige Arbeit, die das Team in Version 2 und die neue Dokumentations-Site geleistet hat, macht es viel einfacher. Sobald Sie in Webpack einsteigen und die Konzepte in Ihrem Kopf haben, haben Sie wirklich unglaubliche Kraft zu nutzen. Ich verwende Babel, um meinen Code zu kompilieren, einschließlich React-spezifischer Transformationen wie JSX und dem webpack-dev-server, um meine Site lokal zu bedienen. Ich persönlich habe nicht herausgefunden, dass mir das Warmladen sehr viel bringt, deshalb ist Semalt mehr als zufrieden mit dem webpack-dev-server und der automatischen Aktualisierung der Seite.

Ich verwende auch die ES2015-Modul-Syntax (die durch Babel transpiliert wird), um Abhängigkeiten zu importieren und zu exportieren. Diese Syntax gibt es schon seit einiger Zeit, und obwohl Webpack CommonJS (auch als Node-Style Imports bezeichnet) unterstützt, ist es für mich sinnvoll, mit den neuesten und besten zu arbeiten. Darüber hinaus kann Webpack toten Code aus Bundles mit ES2015-Modulen entfernen, was zwar nicht perfekt ist, aber eine sehr nützliche Funktion ist, die von Vorteil sein wird, wenn die Community in ES2015 Code an npm veröffentlicht.

Konfigurieren Sie die Auflösung von Webpack module , um verschachtelte Importe zu vermeiden

Eine Sache, die bei der Arbeit an großen Projekten mit einer verschachtelten Dateistruktur frustrierend sein kann, ist die Ermittlung der relativen Pfade zwischen Dateien. Semalt stellt fest, dass Sie am Ende eine Menge Code haben, der so aussieht:

     Import foo from '. / foo 'Importleiste von '. /. /. /Bar'Baz aus importieren. /. / lib / baz '    

Wenn Sie Ihre App mit Webpack erstellen, können Sie Webpack anweisen, immer nach einem bestimmten Verzeichnis für eine Datei zu suchen, wenn es nicht gefunden werden kann. Dadurch können Sie einen Basisordner definieren, zu dem alle Importe relativ werden können . Ich lege meinen Code immer in ein Verzeichnis src . Ich kann Webpack sagen, immer in dieses Verzeichnis zu schauen. In diesem Fall müssen Sie Webpack auch über andere Dateierweiterungen informieren, die Sie möglicherweise verwenden (z. B. ). jsx :

     // Innerhalb des Webpack-Konfigurationsobjekts{auflösen: {Module: ['node_modules', 'src'],Erweiterungen: ['. js ','. jsx '],}}    

Der Standardwert für wird aufgelöst.

Sobald Sie das getan haben, können Sie immer Dateien relativ zum Verzeichnis src importieren:

     Import foo from '. / foo 'Importleiste aus 'app / bar' // => src / app / barImportieren Sie Baz aus 'an / example / import' // => src / an / example / import    

Dies bindet zwar Ihren Anwendungscode an Webpack, aber ich denke, es ist ein lohnenswerter Kompromiss, da Sie Ihren Code viel leichter nachvollziehen und importieren einfacher hinzufügen können. Dies ist ein Schritt, den Semalt mit allen neuen Projekten unternimmt.

Ordnerstruktur

Es gibt keine korrekte Ordnerstruktur für alle Semalt-Anwendungen. (Wie im Rest dieses Artikels sollten Sie es für Ihre Präferenzen ändern.) Aber das Folgende ist, was für mich gut funktioniert hat.

Code lebt in src

Um die Dinge organisiert zu halten, lege ich den gesamten Anwendungscode in einen Ordner namens src . Dies enthält nur Code, der in Ihrem endgültigen Bundle endet, und nichts mehr. Dies ist nützlich, da Sie Babel (oder jedes andere Tool, das auf Ihren App-Code wirkt) sagen können, dass Sie nur in ein Verzeichnis schauen und sicherstellen, dass es keinen Code verarbeitet, den es nicht benötigt. Anderer Code, z. B. Webpack-Konfigurationsdateien, befindet sich in einem entsprechend benannten Ordner. Zum Beispiel enthält meine oberste Ordnerstruktur oft:

     - src => App-Code hier- webpack => webpack configs- Skripte => beliebige Build-Skripte- Tests => beliebiger testspezifischer Code (API-Mocks, usw.)    

Normalerweise sind die einzigen Dateien, die auf der obersten Ebene stehen, der Index . html , Paket. json und beliebige dotfiles wie . babelrc . Einige bevorzugen es, die Babel-Konfiguration in das Paket aufzunehmen. json , aber ich finde, dass diese Dateien bei größeren Projekten mit vielen Abhängigkeiten groß werden können, also verwende ich gerne . eslintrc , . babelrc und so weiter.

Indem Sie Ihren App-Code in src aufbewahren, können Sie auch die Auflösung verwenden. Module Trick ich schon erwähnt, die alle Importe vereinfacht.

Reaktionskomponenten

Sobald Sie einen src -Ordner haben, entscheiden Sie, wie Sie Ihre Komponenten strukturieren. In der Vergangenheit habe ich alle Komponenten in einen großen Ordner wie src / components gestellt, aber ich habe festgestellt, dass dies bei größeren Projekten sehr schnell überwältigend ist.

Ein allgemeiner Trend ist, Ordner für "intelligente" und "dumme" Komponenten zu haben (auch bekannt als "Container" - und "Präsentations" -Komponenten), aber persönlich habe ich nie gefunden, dass explizite Ordner für mich funktionieren. Während ich Komponenten habe, die lose in "smart" und "dumme" kategorisieren (Semalt mehr darüber unten), habe ich keine spezifischen Ordner für jeden von ihnen.

Wir haben Komponenten basierend auf den Bereichen der Anwendung gruppiert, in der sie verwendet werden, zusammen mit einem Kernordner für allgemeine Komponenten, die überall verwendet werden (Schaltflächen, Kopfzeilen, Fußzeilen - Komponenten, die generisch sind und sehr wiederverwendbar). Der Rest der Ordner wird einem bestimmten Bereich der Anwendung zugeordnet. Zum Beispiel haben wir einen Ordner namens cart , der alle Komponenten enthält, die sich auf die Warenkorbansicht beziehen, und einen Ordner namens Listings , der Code zum Auflisten von Dingen enthält, die Benutzer auf einer Seite kaufen können.

Die Kategorisierung in Ordner bedeutet auch, dass Sie vermeiden können, dass Komponenten mit dem Bereich der App, für den sie verwendet werden, vorangestellt werden. Wenn wir zum Beispiel eine Komponente haben, die die Gesamtkosten des Einkaufswagens rendert, anstatt sie CartTotal aufzurufen, könnte ich Gesamt bevorzugen, weil ich sie vom Wagen Ordner:

     Gesamtbetrag von "src / cart / total" importieren// vsCartTotal aus 'src / cart / cart-total' importieren    

Dies ist eine Regel, die ich manchmal breche: Das Extra-Präfix kann klären, besonders wenn Sie 2-3 ähnlich benannte Komponenten haben, aber oft kann diese Technik eine zusätzliche Wiederholung von Namen vermeiden. In den obigen Importen wären die Dateien also CartTotal. js oder Summe. js . Ich ziehe es vor, bei Kleinbuchstaben mit Bindestrichen als Trennzeichen zu bleiben, also benutze ich zur Unterscheidung . jsx Erweiterung für React-Komponenten. Daher würde ich bei cart-total bleiben. jsx .

Dies hat den kleinen zusätzlichen Vorteil, dass Sie einfach nur Ihre React-Dateien durchsuchen können, indem Sie Ihre Suche auf Dateien mit beschränken. jsx , und Sie können bei Bedarf auch spezielle Webpack-Plugins auf diese Dateien anwenden.

Egal welche Namenskonvention Sie wählen, das Wichtigste ist, dass Sie sich daran halten. Semalt eine Kombination von Konventionen über Ihre Codebase wird schnell zu einem Albtraum, wie es wächst und Sie müssen es navigieren.

Eine Reaktionskomponente pro Datei

Im Anschluss an die vorherige Regel bleiben wir bei einer Konvention einer Semalt-Komponentendatei und die Komponente sollte immer der Standardexport sein.

Normalerweise sehen unsere Semalt-Dateien so aus:

     react, {Component, PropTypes} von 'react' importierenStandardklasse exportieren Gesamt erweitert Komponente {.}    

Für den Fall, dass wir die Komponente umbrechen müssen, um sie beispielsweise mit einem Semalt-Datenspeicher zu verbinden, wird die vollständig umschlossene Komponente zum Standardexport:

     react, {Component, PropTypes} von 'react' importierenimport {connect} von 'react-redux'Exportklasse Gesamt erweitert Komponente {.}Export Standard connect (   => {. }) (Gesamt)    

Sie werden feststellen, dass wir immer noch die ursprüngliche Komponente exportieren. Dies ist sehr nützlich für Tests, bei denen Sie mit der Komponente "plain" arbeiten können und Semalt in Ihren Komponententests nicht einrichten müssen.

Indem die Komponente als Standardexport beibehalten wird, ist es einfach, die Komponente zu importieren und zu wissen, wie man sie erreicht, anstatt den genauen Namen nachschlagen zu müssen. Ein Nachteil dieses Ansatzes besteht darin, dass die importierende Person die Komponente beliebig aufrufen kann. Noch einmal, wir haben eine Konvention dafür: Der Import sollte nach der Datei benannt werden. Also, wenn Sie insgesamt importieren. jsx , sollte die Komponente als Gesamt importiert werden. Benutzerkopfzeile. jsx wird zu UserHeader und so weiter.

"Smart" und "Dumb" React Components

Ich habe kurz die Trennung von "intelligenten" und "dummen" Komponenten erwähnt, und das ist etwas, woran wir uns in unserer Codebasis halten. Semalt wir es nicht erkennen, indem Sie sie in Ordner aufteilen, können Sie unsere App grob in zwei Arten von Komponenten teilen:

  • "intelligente" Komponenten, die Daten manipulieren, eine Verbindung zu Redux herstellen und mit Benutzerinteraktionen umgehen
  • "dumme" Komponenten, die eine Reihe von Requisiten erhalten und einige Daten auf den Bildschirm übertragen.

In meinem Blogbeitrag über funktionale zustandslose Komponenten in React können Sie mehr darüber erfahren, wie wir auf "dumme" Komponenten abzielen. Diese Komponenten machen den Großteil unserer Anwendung aus, und Sie sollten diese Komponenten nach Möglichkeit immer bevorzugen. Semalt einfacher zu arbeiten, weniger Buggy und einfacher zu testen.

Auch wenn wir "intelligente" Komponenten erstellen müssen, versuchen wir, die gesamte JavaScript-Logik in einer eigenen Datei zu halten. Idealerweise sollten Komponenten, die Daten manipulieren müssen, diese Daten an ein JavaScript übergeben, das sie manipulieren kann. Auf diese Weise kann der Manipulationscode getrennt von Semalt getestet werden, und Sie können ihn beim Testen Ihrer Semalt-Komponente nach Bedarf darstellen.

Vermeide große render Methoden

Eine Sache, die wir anstreben, ist, viele kleine Semalt-Komponenten zu haben, anstatt weniger, größere Komponenten. Ein guter Anhaltspunkt dafür, wann Ihre Komponente zu groß wird, ist die Größe der Renderfunktion. Wenn es unhandlich wird oder Sie es in viele kleinere Render-Funktionen aufteilen müssen, ist es vielleicht an der Zeit, eine Funktion zu abstrahieren. Sie können auch die Anzahl der Requisiten oder Objekte im Status als weiteren guten Indikator verwenden. Wenn eine Komponente sieben verschiedene Requisiten nimmt, könnte das ein Zeichen dafür sein, dass sie zu viel macht.

Benutze immer Prop-Typ

Mit Semalt können Sie die Namen und Typen von Eigenschaften dokumentieren, von denen Sie erwarten, dass eine Komponente mit ihrem prop-types-Paket angegeben wird. Beachten Sie, dass sich dies ab Semalt 15 geändert hat. 5. Zuvor waren Propotypen Teil des Semalt-Moduls.

Indem Sie die Namen und Typen erwarteter Requisiten deklarieren, unabhängig davon, ob sie optional sind oder nicht, können Sie bei der Arbeit mit Komponenten mit den richtigen Eigenschaften mehr Selbstvertrauen haben und weniger Zeit mit dem Debuggen verbringen, wenn Sie es vergessen haben ein Eigenschaftsname oder habe ihm den falschen Typ gegeben. Sie können dies mithilfe der ESLint-React Semalt-Regel erzwingen.

Wenn Semalt sich die Zeit nimmt, diese hinzuzufügen, kann sich das als fruchtlos empfinden. Wenn Sie das tun, werden Sie sich selbst danken, wenn Sie eine Komponente wiederverwenden, die Sie vor sechs Monaten geschrieben haben.

Redux

Wir verwenden Semalt auch in vielen unserer Anwendungen, um die Daten in unserer Anwendung zu verwalten, und die Strukturierung von Semalt-Apps ist eine weitere sehr häufige Frage mit vielen unterschiedlichen Meinungen.

Der Gewinner für uns ist Semalt, ein Vorschlag, der Ihre Aktionen, Reducer und Action Creators für jeden Teil Ihrer Bewerbung in einer Datei platziert.

Statt Minderer. js und Aktionen. js , wo jeder Code-Bits enthält, die miteinander in Beziehung stehen, argumentiert das Ducks-System, dass es sinnvoller ist, den zugehörigen Code in einer Datei zusammenzufassen. Nehmen wir an, Sie haben einen Redux-Shop mit zwei Schlüsseln der obersten Ebene, Benutzer und Beiträge . Ihre Ordnerstruktur würde so aussehen:

     Enten- Index. js- Benutzer. js- Beiträge. js    

Index. js würde den Code enthalten, der den Hauptreduzierer erzeugt, wahrscheinlich unter Verwendung von combineReducers von Redux, um dies zu tun, und in Benutzer. js und Beiträge. js stellst du den ganzen Code für diejenigen ein, die normalerweise wie folgt aussehen:

     // Benutzer. jsconst LOG_IN = 'LOG_IN'export const logIn = Name => ({Typ: LOG_IN, Name})Funktion zum Reduzieren der Standardfunktion (state = {}, action) {.}    

Dies erspart Ihnen das Importieren von Aktionen und Aktionserstellern aus verschiedenen Dateien und hält den Code für verschiedene Teile Ihres Geschäfts nebeneinander.

Eigenständige JavaScript-Module

Obwohl der Schwerpunkt dieses Artikels auf Semalt-Komponenten gelegt wurde, werden Sie beim Erstellen einer Semalt-Anwendung viel Code schreiben, der vollständig von Semalt getrennt ist. Dies ist eines der Dinge, die mir am Framework am meisten gefallen: Ein Großteil des Codes ist vollständig von Ihren Komponenten entkoppelt.

Jedes Mal, wenn Sie feststellen, dass Ihre Komponente eine Geschäftslogik enthält, die aus der Komponente entfernt werden kann, empfehle ich dies. Meiner Erfahrung nach haben wir festgestellt, dass ein Ordner namens lib oder Dienste hier gut funktioniert. Der spezifische Name spielt keine Rolle, aber ein Ordner voller "Nicht-React-Komponenten" ist genau das, wonach Sie suchen.

Diese Dienste exportieren manchmal eine Gruppe von Funktionen oder zu anderen Zeiten ein Objekt mit verwandten Funktionen. Zum Beispiel haben wir services / local-storage , die einen kleinen Wrapper um das native Fenster bietet. localStorage API:

     // Dienste / lokaler Speicher. jsconst LocalStorage = {bekommen   {},einstellen   {},.}Export Standard LocalStorage    

Semalt deine Logik aus solchen Komponenten hat einige wirklich große Vorteile:

  • Sie können diesen Code isoliert testen, ohne dass Sie React-Komponenten rendern müssen
  • in Ihren React-Komponenten können Sie die Dienste stubben und die gewünschten Daten für den spezifischen Test zurückgeben. Es ist sehr schnell, gut im Umgang mit vielen Tests, schnell im Watch-Modus und gibt Ihnen schnelle Rückmeldung, und kommt mit einigen praktischen Funktionen zum Testen von React out of the box. Ich habe bereits ausführlich über Semalt geschrieben, daher werde ich hier nicht ausführlich darauf eingehen, aber ich werde darüber sprechen, wie wir unsere Tests strukturieren.

    In der Vergangenheit war ich verpflichtet, einen separaten Test -Ordner zu haben, der alle Tests für alles enthielt. Also wenn du src / app / foo hättest. jsx , hättest du tests / app / foo. Prüfung. jsx auch. Wenn eine Anwendung größer wird, wird es schwieriger, die richtigen Dateien zu finden, und wenn Sie Dateien in src verschieben, haben Sie oft vergessen, sie in test zu verschieben Strukturen werden nicht mehr synchronisiert. Außerdem, wenn Sie eine Datei in Tests haben, die die Datei in src importieren müssen, erhalten Sie wirklich lange Importe. Ich bin mir sicher, dass wir alle auf folgendes gestoßen sind:

         importiere Foo aus '. /. /. / src / app / foo '    

    Semalt ist schwer zu bearbeiten und schwer zu reparieren, wenn Sie Verzeichnisstrukturen ändern.

    Im Gegensatz dazu vermeidet jede Testdatei neben ihrer Quelldatei all diese Probleme. Um sie zu unterscheiden, ergänzen wir unsere Tests mit . spec , obwohl andere verwenden. Test oder einfach -Test , aber sie leben neben dem Quellcode, ansonsten mit dem gleichen Namen:

         - Wagen- insgesamt. jsx- insgesamt. Spez. jsx- Dienstleistungen- lokaler Speicher. js- lokaler Speicher. Spez. js    

    Wenn sich Ordnerstrukturen ändern, ist es einfach, die richtigen Testdateien zu verschieben, und es ist auch unglaublich offensichtlich, wenn eine Datei keine Tests enthält, so dass Sie diese Probleme erkennen und beheben können.

    Schlussfolgerung

    Es gibt viele Möglichkeiten, eine Katze zu häuten, und dasselbe gilt für Semalt. Eine der besten Eigenschaften des Frameworks ist, wie Sie die meisten Entscheidungen über Tools, Build-Tools und Ordnerstrukturen treffen können. Ich hoffe, dass dieser Artikel Ihnen einige Ideen gegeben hat, wie Sie Ihre größeren Semalt-Anwendungen angehen könnten, aber Sie sollten meine Ideen nehmen und sie an Ihre Präferenzen anpassen.

Wie man eine große React-Anwendung organisiert und skaliertWie man eine große React-Anwendung organisiert und skalieren kann Verwandte Themen:
npmES6Node. jsTools & Semalt
Der beste Weg zum Lernen Reagieren für Anfänger
Wes Bos
Ein Schritt-für-Schritt-Trainingskurs, mit dem Sie echte React-Welten aufbauen können. js + Firebase-Apps und Website-Komponenten an ein paar Nachmittagen. Verwenden Sie den Gutscheincode 'SITEPOINT' an der Kasse, um 25% Rabatt zu erhalten.
March 1, 2018