Ruby on Rails-modularisering med Packwerk Episode II
Nicolas Nisoria
I den andre episoden av vår Ruby on Rails-modularisering med Packwerk skal vi se nærmere på konseptet med applikasjonen som en pakke.
Søknad som en pakke
Tilnærmingen for å modularisere applikasjonen vår består i å konvertere hele applikasjonen til en pakke.
Opprett strukturen
Først må vi opprette app/pakker mappen der vi skal plassere alle pakkene våre. For å isolere pakkene våre må vi skille hver MVC-konseptet i én mappe. Ved å ta CodeTriage prosjekt som et eksempel vil vi ha noe som ligner på følgende bilde.
Hvis vi prøver å kjøre serveren, vil den ikke finne konstantene. Derfor må vi legge til en konfigurasjonslinje i application.rb
Strukturen vår er klar, så nå kan vi begynne å opprette pakkene. For å gjøre det trenger vi bare å legge til enpackage.yml til hver mappe med følgende konfigurasjon:
enforce_privacy: false
enforce_dependencies: true
enforce_privacygir oss muligheten til å isolere alle konstantene i pakken og arbeide med et offentlig API. For å eksponere de offentlige konstantene, må vi legge til konstantene i for eksempel pakker/brukere/app/public.Foreløpig skal vi sette denne konfigurasjonen til falsk.
enforce_dependencies vil håndheve avhengigheten til en pakke og se etter alle konstante referanser. Hvis en avhengighet ikke er eksplisitt definert, vil det være et brudd på grensene.
Validering av pakkesystemet
Packwerk etablert et kriterium vi må følge for å ha et gyldig pakkesystem. Vi kan begynne å kjøre packwerk validere i konsollen vår.
Dette vil sjekke mappestrukturen vår, pakkekonfigurasjonog autoload banebuffer.
Akkurat nå er ikke applikasjonen vår gyldig, og vi må fikse lastestiene ipackwerk.yml. For å gjøre dette trenger vi bare å legge til de manglende stiene.
Nå er vi klare til å sjekke grenseoverskridelser i applikasjonen vår. For å sjekke brudd kan vi kjørepackwerk update-deprecations vil denne kommandoen generere utdaterte_referanser.yml fil for hver pakke. I hver fil finner vi pakkenavn, type brudd og filbane. Med all denne informasjonen vet vi hvor overtredelsen skjer, og vi kan ta en beslutning om å løse den.
I dette eksemplet skal vi beskrive alle deler av informasjonen som genereres av Packwerk.
– app/packages/repos - pakke der konstantbruddet er funnet.
– ::Repo - stien til filen som inneholder den brutte konstanten.
– avhengighet - en type krenkelse, enten avhengighet eller personvern.
– app/packages/users/models/user.rb - stien til filen som inneholder den brutte konstanten.
Som et siste trinn i denne delen, ikke glem å legge til de nye genererte filbanene i packwerk.yml og kjør valideringene på nytt.
Visualisering av avhengighet
Med all informasjonen i package.yml og utdaterte_referanser.ymlVi kan da visualisere en graf over avhengigheter. For å gjøre det må vi legge til en annen perle, i dette tilfellet vil vi bruke Pocky.
Løpende rive pocky:generere vil vi generere en fil som heter packwerk.png der vi kan visualisere vår første graf over avhengigheter.
Når alle pakkene er definert, ser grafen vår slik ut.
avhengigheter allerede eksisterer, men det betyr ikke at de er akseptert av Packwerk. Til akseptere en avhengighet, må vi legge til avhengighetskonfigurasjon i package.yml i hver pakke. Vi vil fokusere på mail_builders siden det er en pakke uten sirkulær avhengighet. Det er verdt å nevne at Packwerk lar oss ikke akseptere sirkulære avhengigheter.
Etter at du har lagt til denne konfigurasjonen, Pocky vil farge de aksepterte avhengighetene med grønt.
Vi kan slette utdaterte_referanser.yml fra app/packages/mail_builders og kjøre packwerk update-deprecations igjen. Filen vil ikke bli generert på nytt, siden alle brudd ble rettet for denne pakken. Det er viktig å nevne at selv om vi ikke bruker Graph med aksepterte avhengigheter
Ruby on Rails-modularisering med Packwerk akseptere avhengigheter vil applikasjonen vår fortsatt fungere som før, men nå har vi flere informasjon for å ta beslutninger og gjøre endringer.
Fjern sirkulære avhengigheter
I den forrige grafen vår hadde vi mange sirkulære avhengigheter som måtte løses på en eller annen måte. Vi har ulike strategier for å gjøre det:
- Utfør avhengighetsinjeksjon eller avhengighetsinjeksjon med typing.
Et problem her er at vi må kjenne kodebasen for å kunne gjøre en skikkelig refaktorering. Jeg er ikke så godt kjent med kodebasen til dette prosjektet siden jeg tok det som et eksempel, så av praktiske grunner vil vi gå for den første strategien, å ikke gjøre noe. Selv om vi vil unngå det meste av refaktorering, ønsker vi å jobbe med avhengighetene i rot pakke.
Rotpakken inneholder alt limet fra Rails-rammeverket, alle klassene vi arver fra og får alle til å fungere sammen. Så for å løse de sirkulære avhengighetene, skal vi opprette en ny pakke kalt rails i følgende trinn:
Flytt alle applikasjonsfiler og -mapper fra appen til app/packages/rails.
Opprett enpackage.yml for pakken med samme konfigurasjon som de foregående pakkene.
Legg til alle de nye filbanene i packwerk.yml.
Legg til app/packages/rails som en avhengighet fra resten av pakkene.
Når vi har opprettet pakken, vil vi begynne å legge merke til mange filer som kan struktureres på nytt. Etter å ha flyttet alt til den tilsvarende pakken og akseptert avhengigheter får vi en ny struktur og en renere graf.
Fjern avhengigheter fra rotpakken
Nå ser grafen vår mye bedre ut, og det ville vært flott hvis vi kunne fjerne alle avhengighetene fra rotpakken. Hvis vi sjekker deprecated_references.yml i rotpakken, vil vi legge merke til at de fleste av dem er fra test , lib/tasks , db og konfigurasjon mappe. For å løse disse avhengighetene skal vi opprette en testmappe i hver pakke. Å ha noe sånt som app/pakker/brukere/test. Deretter skal vi ekskludere lib/tasks , db og konfigurasjonblant andre mapper fra Packwerk siden disse avhengighetene egentlig ikke er viktige i analysen vår, og vi ikke har noen enkel måte å løse dem på. Vi vil legge til følgende i vår packwerk.yml.
Når vi har flyttet alle testene fra rotpakken og ekskludert mappene fra analysen, får vi en ny graf uten rotavhengigheter.
Som vi ser, har vi fortsatt sirkulære avhengigheter ibrukere , repos , og dokumenter . Selv om vi ikke løste dem, har vi viktig informasjon å formidle nå. Vi vet at alle team som utfører endringer i en av disse pakkene, vil sannsynligvis måtte utføre endringer i pakkene med den sirkulære avhengigheten. På den annen side vet vi at et team kan jobbe med github_fetchers utelukkende å vite hvilke pakker som er blir påvirket av endringene i hvert øyeblikk.
Det endelige resultatet av prosjektet finner du her her.
Neste trinn
Som et neste trinn kan du håndheve konstant personvern i hver pakke og bare eksponere det offentlige API-et som vil være tilgjengelig fra andre pakker. Du kan enkelt konfigurere hvor API-et ditt skal plasseres i package.yml.
Packwerk gir oss mye informasjon om applikasjonen vår, og med den informasjonen kan vi ta beslutninger for å forbedre arbeidsflyten til teamene våre. Selv om prosessen så ut til å være lang og med mange konfigurasjoner, trenger det ikke alltid å være slik. Vi kan begynne med å opprette pakker bare for den nye koden som legges til i applikasjonen, og deretter modulere gradvis. Så nå kan vi begynne å snakke om gradvis modularisering, et konsept introdusert av Stephan Hagemann "For første gang kan vi bestemme oss for å begynne å modularisere en del av koden på en ambisiøs måte ... Dette gjør det mulig for oss å skape et gradvis voksende støttesystem mot en bedre applikasjonsstruktur."