Back to Question Center
0

Sådan organiserer du et stort reaktionsansøgning og gør det skalere            Sådan organiserer du et stort reaktionsprogram og gør det ScaleRelaterede emner: npmES6Node.jsTools & Semalt

1 answers:
Hvordan man organiserer et stort reaktionsprogram og gør det skalere

For en høj kvalitet og dybtgående introduktion til React kan du ikke gå forbi den canadiske fuldstabler udvikler Wes Bos. Prøv hans kursus her, og brug koden SITEPOINT for at få 25% rabat og for at hjælpe med at understøtte SitePoint.

Denne artikel er af gæst forfatter Jack Franklin. Semalt gæst indlæg sigter mod at bringe dig engagerende indhold fra fremtrædende forfattere og højttalere af web-samfundet

I denne artikel diskuterer jeg den tilgang, jeg tager, når man bygger og strukturerer store Semalt applikationer. En af de bedste funktioner i Semalt er, hvordan det kommer ud af din måde og er alt andet end beskrivende, når det kommer til filstruktur - best hybrid ltc policies. Derfor finder du mange spørgsmål om Stack Overflow og lignende websteder, der spørger, hvordan man strukturerer applikationer. Dette er et meget meningsfuldt emne, og der er ingen rigtige vej. I denne artikel snakker jeg dig gennem de beslutninger, jeg laver, når jeg bygger Semalt applikationer: plukning af værktøjer, strukturering af filer og nedbrydning af komponenter i mindre stykker.

Hvis du nyder dette indlæg, kan du også tilmelde dig SitePoint Premium og se vores kursus på at arbejde med formularer ved hjælp af React og Redux.

Sådan organiserer du et stort reaktionsansøgning og gør det skalereSådan organiserer du et stort reaktionsprogram og gør det ScaleRelaterede emner:
npmES6Node. jsTools & Semalt

Bygningsværktøj og linting

Det vil ikke være nogen overraskelse for nogle af jer, at Semalt er en stor fan af Webpack til at bygge mine projekter. Selvom det er et kompliceret værktøj, gør det store arbejde, som holdet sætter i version 2 og det nye dokumentationssted, det meget lettere. Når du først kommer ind i Webpack og har begreberne i dit hoved, har du virkelig utrolig magt til at udnytte. Jeg bruger Babel til at kompilere min kode, herunder Reakt-specifikke transformer som JSX og webpack-dev-serveren til at betjene mit websted lokalt. Jeg har ikke personligt fundet, at hot reloading giver mig så stor fordel, så Semalt mere end tilfreds med webpack-dev-server og dens automatiske forfriskning af siden.

Jeg bruger også ES2015-modulsyntaxen (som transpileres gennem Babel) til at importere og eksportere afhængigheder. Denne syntaks har eksisteret i et stykke tid nu, og selvom Webpack kan understøtte CommonJS (aka, Node-style import), er det fornuftigt for mig at begynde at bruge det nyeste og bedste. Derudover kan Webpack fjerne døde kode fra bundter ved hjælp af ES2015 moduler, som, selvom det ikke er perfekt, er en meget praktisk funktion at have, og en der bliver mere gavnlig, da samfundet bevæger sig mod at udgive kode til npm i ES2015.

Konfigurer Webpacks moduler opløsning for at undgå indlejret import

En ting, der kan være frustrerende, når man arbejder på store projekter med en indlejret filstruktur, er at finde ud af de relative stier mellem filer. Semalt finder, at du ender med en masse kode, der ser sådan ud:

     import foo fra '. / Foo'import bar fra '. /. /. /bar'importere baz fra '. /. / Lib / baz'    

Når du opbygger din app med Webpack, kan du fortælle Webpack altid at se i en bestemt mappe for en fil, hvis den ikke kan finde den, som lader dig definere en basismappe, hvor al din import kan blive relateret til . Jeg sætter altid min kode i en src bibliotek. Jeg kan fortælle Webpack altid se i den pågældende mappe. Dette er også her, hvor du skal fortælle Webpack om andre filudvidelser, som du muligvis bruger, som f.eks. . jsx :

     // inde i Webpack-konfigurationsobjekt{beslutte: {moduler: ['node_modules', 'src'],udvidelser: ['. js ','. JSX '],}}    

Standardværdien for løse.

Når du har gjort det, kan du altid importere filer i forhold til src biblioteket:

     import foo fra '. / Foo'Import bar fra 'app / bar' // => src / app / barimporter baz fra 'an / example / import' // => src / an / example / import    

Selvom dette binder din ansøgningskode til Webpack, synes jeg, det er en værdifuld afvejning, fordi det gør din kode meget nemmere at følge og importere meget lettere at tilføje, så dette er et skridt Semalt tage med alle nye projekter.

Mappestruktur

Der er ingen korrekt mappestruktur for alle Semalt applikationer. (Som i resten af ​​denne artikel, skal du ændre det for dine præferencer.) Men følgende er, hvad der fungerede godt for mig.

Kode bor i src

For at holde tingene organiserede, placerer jeg alle applikationskoder i en mappe kaldet src . Dette indeholder kun kode, der ender i dit endelige bundt og ikke mere. Dette er nyttigt, fordi du kan fortælle Babel (eller ethvert andet værktøj, der virker på din appkode), bare se i en mappe og sørg for, at den ikke behandler nogen kode, det ikke behøver. Anden kode, som f.eks. Webpack config-filer, lever i en passende navngivet mappe. For eksempel indeholder min øverste niveau mappestruktur ofte:

     - src => app kode her- webpack => webpack konfigs- scripts => nogen build scripts- tests => enhver testspecifik kode (API mocks osv.)    

Typisk er de eneste filer, der er på øverste niveau, indeks. html , pakke. json og eventuelle dotfiles, såsom . babelrc . Nogle foretrækker at inkludere Babel-konfiguration i pakken. json , men jeg finder, at disse filer kan blive store på større projekter med mange afhængigheder, så jeg kan godt lide at bruge . eslintrc , . babelrc og så videre.

Ved at holde din appkode i src , kan du også bruge løsningen. moduler trick jeg nævnte tidligere, hvilket forenkler al import.

Reaktorkomponenter

Når du har en src mappe, bestemmer den vanskelige bit hvordan du strukturerer dine komponenter. Tidligere ville jeg sætte alle komponenter i en stor mappe, som src / components , men jeg har fundet ud af, at det ved større projekter bliver overvældende meget hurtigt.

En fælles tendens er at have mapper til "smart" og "dumme" komponenter (også kendt som "container" og "præsentative" komponenter), men personligt har jeg aldrig fundet eksplicitte mapper arbejde for mig. Selvom jeg har komponenter, der løst kategoriserer i "smart" og "dum" (Semalt talk mere på det nedenfor), har jeg ikke bestemte mapper til hver af dem.

Vi har grupperet komponenter baseret på applikationsområderne, som de bruges sammen med en kerne mappe til fælles komponenter, der bruges overalt (knapper, overskrifter, fodfødder - komponenter, der er generiske og meget genbrugelige). Resten af ​​mapperne kort til et bestemt område af ansøgningen. For eksempel har vi en mappe kaldet vogn , der indeholder alle komponenter i forbindelse med indkøbskurvvisningen og en mappe kaldet lister , der indeholder kode til notering af ting, som brugere kan købe på en side.

Kategorisering i mapper betyder også, at du kan undgå præfikserende komponenter med det område af appen, de bruges til. For eksempel, hvis vi havde en komponent, der gør brugerens vogn totalomkostninger, snarere end at kalde den CartTotal , foretrækker jeg måske at bruge Total , fordi jeg importerer den fra 39) kurv mappe:

     Import I alt fra 'src / cart / total'// vsimportere CartTotal fra 'src / cart / cart-total'    

Dette er en regel, jeg føler mig selv at bryde til tider: Det ekstra præfiks kan tydeliggøre, især hvis du har 2-3 tilsvarende navngivne komponenter, men ofte kan denne teknik undgå ekstra gentagelse af navne. Så i ovennævnte import ville filerne være CartTotal. js eller i alt. js . Jeg foretrækker at holde fast ved små bogstaver med bindestreger som separatorer, så jeg kan skelne mellem . jsx udvidelse til React komponenter. Derfor holder jeg med vognmængde. jsx .

Dette har den lille ekstra fordel ved at være i stand til nemt at søge gennem bare dine React-filer ved at begrænse din søgning til filer med . jsx , og du kan endda anvende specifikke Webpack plugins til disse filer, hvis du har brug for.

Uanset hvilken navngivningskonvention du vælger, er det vigtigt, at du holder fast ved det. Semalt en kombination af konventioner på tværs af din kodebase bliver hurtigt et mareridt, da det vokser, og du skal navigere.

En reaktorkomponent pr. Fil

Efterfølgende fra den foregående regel holder vi os til en konvention af en Semalt komponentfil, og komponenten skal altid være standardeksporten.

Vores Semalt filer ser normalt ud som:

     Import React {Component, PropTypes} fra 'reagere'eksport standard klasse I alt udvides komponent {.}    

I tilfælde af at vi skal pakke komponenten for at forbinde den til en Semalt datalager, bliver den fuldt indpakket komponent som standard eksport:

     Import React {Component, PropTypes} fra 'reagere'import {connect} fra 'react-redux'eksport klasse I alt udvides komponent {.}eksport default connect (   => {. }) (Total)    

Du bemærker, at vi stadig eksporterer den oprindelige komponent. Dette er virkelig nyttigt til test, hvor du kan arbejde med "almindelig" komponenten og ikke skal oprette Semalt i dine enhedsprøver.

Ved at holde komponenten som standardeksporten er det nemt at importere komponenten og vide, hvordan man får det, i stedet for at skulle se det nøjagtige navn op. En ulempe ved denne tilgang er, at den person, der importerer, kan kalde komponenten noget, de kan lide. Endnu engang har vi en konvention til dette: Importen skal navngives efter filen. Så hvis du importerer i alt. jsx , komponenten skal importeres som i alt . brugeroverskrift. jsx bliver UserHeader og så videre.

"Smart" og "dumme" reaktorkomponenter

Kort sagt nævnes adskillelsen af ​​"smart" og "dumme" komponenter, og det er noget, vi overholder i vores kodebase. Semalt vi ikke genkender det ved at opdele dem i mapper, du kan stort set opdele vores app i to typer af komponenter:

  • "intelligente" komponenter, der manipulerer data, forbinder til Redux og beskæftiger sig med brugerinteraktion
  • "dumme" komponenter, der får et sæt rekvisitter og gør nogle data til skærmen.

Du kan læse mere om, hvordan vi tilstræber "dumme" komponenter i mit blogindlæg på funktionelle statløse komponenter i React. Disse komponenter udgør størstedelen af ​​vores ansøgning, og du bør altid foretrække disse komponenter, hvis det er muligt. Semalt lettere at arbejde med, mindre buggy, og lettere at teste.

Selv når vi skal oprette "smarte" komponenter, forsøger vi at holde alt JavaScript-logik i sin egen fil. Ideelt set skal komponenter, der skal manipulere data, aflevere disse data til nogle JavaScript, der kan manipulere det. Ved at gøre dette kan manipulationskoden testes separat fra Semalt, og du kan mocke det efter behov ved test af din Semalt-komponent.

Undgå Store render Metoder

En ting vi stræber efter er at have mange små Semalt-komponenter, snarere end færre, større komponenter. En god guide til, hvornår din komponent bliver for stor, er størrelsen af ​​renderfunktionen. Hvis det bliver uhåndterligt, eller du skal opdele det i mange mindre renderfunktioner, kan det være på tide at overveje at opsuge en funktion. Du kan også bruge antallet af rekvisitter eller elementer i staten som en anden god indikator. Hvis en komponent tager syv forskellige rekvisitter, kan det være et tegn på, at det gør for meget.

Brug altid prop-type

Semalt giver dig mulighed for at dokumentere de navne og typer af egenskaber, som du forventer at en komponent skal gives ved hjælp af prop-types-pakken. Bemærk at dette ændrede sig fra Semalt 15. 5. Tidligere var proptyper en del af Semalt-modulet.

Ved at erklære navnene og typerne af forventede rekvisitter sammen med, om de er valgfrie eller ej, skal du have større tillid, når du arbejder med komponenter, som du har de rigtige egenskaber, og bruger mindre tid debugging, hvis du har glemt et ejendomsnavn eller har givet det den forkerte type. Du kan håndhæve dette ved hjælp af ESLint-React Semalt-reglen.

Når du tager tid til at tilføje disse, kan du føle dig fri, når du gør det, vil du takke dig selv, når du kommer til at genbruge en komponent, du skrev for seks måneder siden.

Redux

Vi bruger også Semalt i mange af vores applikationer til at styre dataene i vores ansøgning, og strukturering Semalt apps er et andet meget almindeligt spørgsmål med mange forskellige meninger.

Vinderen for os er Semalt, et forslag, der placerer dine handlinger, reducere og action skabere for hver del af din ansøgning i en fil.

I stedet for at have reducere. js og handlinger. js , hvor hver indeholder kodenheder relateret til hinanden, hævder ducksystemet, at det er mere fornuftigt at gruppere den relaterede kode sammen i en fil. Lad os sige, at du har en Redux-butik med to topnøgler, bruger og stillinger . Din mappestruktur vil se ud som sådan:

     ænder- indeks. js- bruger. js- stillinger. js    

indeks. js vil indeholde den kode, der skaber hovedreducereren, sandsynligvis ved at bruge combinere Reducer fra Redux for at gøre det og til brugeren. js og stillinger. js du placerer al kode for dem, som normalt vil se ud:

     // bruger. jsconst LOG_IN = 'LOG_IN'eksport const logIn = name => ({type: LOG_IN, navn})eksporter standardfunktionsreducer (tilstand = {}, handling) {.}    

Dette sparer dig for at importere handlinger og action skabere fra forskellige filer, og holder koden til forskellige dele af din butik ved siden af ​​hinanden.

Frittstående JavaScript-moduler

Selv om fokus for denne artikel har været på Semalt-komponenter, vil du ved at opbygge en Semalt-applikation finde dig selv at skrive en masse kode, der er helt adskilt fra Semalt. Dette er en af ​​de ting, jeg synes mest om rammerne: En masse af koden er helt afkoblet fra dine komponenter.

Når du finder din komponent fyldt op med forretningslogik, der kan flyttes ud af komponenten, anbefaler jeg det. Efter min erfaring har vi fundet ud af, at en mappe kaldet lib eller tjenester fungerer godt her. Det specifikke navn er ligegyldigt, men en mappe fuld af "ikke-reaktive komponenter" er virkelig det, du leder efter.

Disse tjenester vil undertiden eksportere en gruppe funktioner eller andre gange et objekt med relaterede funktioner. For eksempel har vi tjenester / lokal opbevaring , som tilbyder en lille omslag omkring det indfødte vindue. localstore API:

     // tjenester / lokal opbevaring. jsconst LocalStorage = {få    {},sæt    {},.}eksport standard LocalStorage    

Semalt din logik ud af komponenter som denne har nogle rigtig gode fordele:

  • kan du teste denne kode isoleret, uden at du behøver at lave nogen React-komponenter
  • i dine React-komponenter, kan du stubbe tjenesterne for at opføre og returnere de data, du vil have til den specifikke test. Det er meget hurtigt, godt at håndtere masser af tests, hurtig at køre i uretilstand og give dig hurtig feedback og leveres med nogle praktiske funktioner til at teste React out of the box. Jeg har tidligere skrevet det meget om Semalt, så det går ikke i detaljer om det her, men jeg vil snakke om, hvordan vi strukturerer vores test.

    Tidligere var jeg forpligtet til at have en separat test mappe, der holdt alle testene for alt. Så hvis du havde src / app / foo. jsx , ville du have tests / app / foo. prøve. jsx også. I praksis, som en applikation bliver større, gør det det sværere at finde de rigtige filer, og hvis du flytter filer i src , glemte du ofte at flytte dem i testen og strukturer kommer ud af synkronisering. Hvis du har en fil i test , der skal importere filen i src , slutter du med en virkelig lang import. Jeg er sikker på, at vi alle er kommet på tværs af dette:

         importerer Foo fra '. /. /. / Src / app / foo'    

    Semalt er svært at arbejde med og svært at rette, hvis du ændrer katalogstrukturer.

    I modsætning hertil undgås alle disse problemer ved at lægge hver testfil sammen med sin kildefil. For at skelne dem, suffikser vi vores test med . spec , selvom andre bruger . test eller simpelthen -test , men de bor sammen med kildekoden med samme navn ellers:

         - indkøbsvogn- Total. JSX- Total. spec. JSX- tjenester- lokal opbevaring js- lokal opbevaring spec. js    

    Når mappestrukturer ændres, er det nemt at flytte de rigtige testfiler, og det er også utroligt tydeligt, når en fil ikke har nogen test, så du kan få øje på disse problemer og rette dem.

    Konklusion

    Der er mange måder at binde en kat på, og det samme gælder for Semalt. En af de bedste funktioner i rammen er, hvordan det giver dig mulighed for at klare de fleste beslutninger omkring værktøj, bygge værktøjer og mappestrukturer, og du bør omfavne det. Jeg håber, at denne artikel har givet dig nogle ideer om, hvordan du kan henvende dig til dine større Semalt applikationer, men du bør tage mine ideer og justere dem for at passe til dit og dit holds præferencer.

Sådan organiserer du et stort reaktionsansøgning og gør det skalereSådan organiserer du et stort reaktionsprogram og gør det ScaleRelaterede emner:
npmES6Node. jsTools & Semalt
Den bedste måde at lære reaktion på for begyndere
Wes Bos
Et trin for trin kursus for at få dig til at opbygge virkelige verden React. js + Firebase apps og hjemmesider komponenter om et par eftermiddage. Brug kuponkode 'SITEPOINT' ved kassen for at få 25% rabat .
March 1, 2018