Ruby on Rails modularisatie met Packwerk Episode II
Nicolas Nisoria
In de tweede aflevering van onze Ruby on Rails modularisatie met Packwerk nemen we het concept van applicatie als pakket onder de loep.
Toepassing als pakket
De aanpak om onze applicatie te modulariseren bestaat uit het omzetten van de hele applicatie in een pakket.
Creëer de structuur
Eerst moeten we app/pakketten map waar we al onze pakketten zullen plaatsen. Om onze pakketten te isoleren moeten we elke MVC-concept in één map. De CodeTriage project Als voorbeeld hebben we zoiets als de volgende afbeelding.
Als we de server proberen te starten, zal hij de constanten niet vinden. Daarom moeten we een configuratieregel toevoegen aan onze toepassing.rb
Onze structuur is klaar, dus nu kunnen we beginnen met het maken van de pakketten. Om dat te doen, hoeven we alleen maar eenpackage.yml naar elke map met de volgende configuratie:
privacy afdwingen: false
afhankelijkheden afdwingen: waar
privacy afdwingengeeft ons de mogelijkheid om alle constanten van het pakket te isoleren en te werken met een openbare API. Om de publieke constanten zichtbaar te maken, moeten we de constanten toevoegen in bijvoorbeeld pakketten/gebruikers/app/public.Voor nu gaan we deze configuratie instellen op vals.
afhankelijkheden afdwingen zal de afhankelijkheid van een pakket afdwingen en controleren op alle constante verwijzingen. Als een afhankelijkheid niet expliciet is gedefinieerd, is dit een schending van de grens.
Het pakketsysteem valideren
Packwerk een criterium vastgesteld dat we moeten volgen om een geldig pakketsysteem te hebben. We kunnen beginnen met het uitvoeren van pakwerk geldig in onze console.
Hiermee wordt onze mappenstructuur gecontroleerd, pakketconfiguratieen autoload padcache.
Op dit moment is onze applicatie niet geldig en moeten we de laadpaden inpakwerk.yml. Om dit te doen, hoeven we alleen de ontbrekende paden toe te voegen.
Op dit punt zijn we klaar om grensschendingen in onze applicatie te controleren. Om schendingen te controleren kunnen we het volgende uitvoerenpackwerk update-deprecations zal dit commando het volgende genereren verouderde_verwijzingen.yml bestand voor elk pakket. In elk bestand vinden we de pakketnaam, het type overtreding en het bestandspad. Met al deze informatie weten we waar de schending plaatsvindt en kunnen we een beslissing nemen om de schending op te lossen.
Aan de hand van het voorbeeld gaan we elk deel van de gegenereerde informatie beschrijven door Packwerk.
– app/pakketten/repos - pakket waar de constante schending is gevonden.
– ::Repo - pad naar het bestand met de geschonden constante.
– afhankelijkheid - een type schending, afhankelijkheid of privacy.
– app/pakketten/gebruikers/modellen/gebruiker.rb - pad naar het bestand met de geschonden constante.
Vergeet als laatste stap in dit onderdeel niet om de nieuwe gegenereerde bestandspaden toe te voegen aan pakwerk.yml en voer de validaties opnieuw uit.
Visualisatie van afhankelijkheid
Met alle informatie in package.yml en verouderde_verwijzingen.ymldan kunnen we een grafiek van afhankelijkheden visualiseren. Om dat te doen moeten we nog een gem toevoegen, in dit geval gebruiken we Pocky.
Lopende hark pocky:genereren genereren we een bestand met de naam pakwerk.png waar we onze eerste grafiek van afhankelijkheden kunnen visualiseren.
Met alle pakketten gedefinieerd ziet onze grafiek er als volgt uit.
afhankelijkheden bestaan al, maar dat betekent niet dat ze worden geaccepteerd door Packwerk. Naar een afhankelijkheid accepteren, moeten we de afhankelijkhedenconfiguratie toevoegen aan de package.yml in elk pakket. We richten ons op mail_bouwers omdat het een pakket is zonder circulaire afhankelijkheid. Het is het vermelden waard dat Packwerk laat ons geen circulaire afhankelijkheden accepteren.
Na het toevoegen van deze configuratie, Pocky zal de geaccepteerde afhankelijkheden groen kleuren.
We kunnen verwijderen verouderde_verwijzingen.yml van app/pakketten/mail_bouwers en ren packwerk update-deprecations opnieuw. Het bestand wordt niet opnieuw gegenereerd omdat alle schendingen werden opgelost voor dit pakket. Het is belangrijk om te vermelden dat zelfs als we niet Graph met geaccepteerde afhankelijkheden
Ruby on Rails modularisatie met Packwerk afhankelijkheden accepteren zal onze applicatie nog steeds werken zoals voorheen, maar nu hebben we meer informatie om beslissingen te nemen en te refactoren.
Circulaire afhankelijkheden verwijderen
In onze vorige grafiek hadden we veel circulaire afhankelijkheden die op de een of andere manier moesten worden opgelost. We hebben verschillende strategieën om dat te doen:
- Voer afhankelijkheidsinjectie of afhankelijkheidsinjectie met typing uit.
Een probleem hierbij is dat om een goede refactor uit te voeren, we de codebase moeten kennen. Ik ben niet zo bekend met de codebase van dit project omdat ik het als voorbeeld heb genomen, dus om praktische redenen gaan we voor de eerste strategie, niets doen. Zelfs als we het grootste deel van het refactoren vermijden, willen we werken aan de afhankelijkheden in de wortel pakket.
Het rootpakket bevat alle lijm van de Rails raamwerkAlle klassen waar we van erven en laten samenwerken. Dus, om de circulaire afhankelijkheden op te lossen, gaan we een nieuw pakket maken met de naam rails in de volgende stappen:
Verplaats alle applicatie_ bestanden en mappen van de app naar app/pakketten/rails.
Maak eenpackage.yml voor het pakket met dezelfde configuratie als de vorige pakketten.
Voeg alle nieuwe bestandspaden toe aan pakwerk.yml.
Voeg toe app/pakketten/rails als een afhankelijkheid van de rest van de pakketten.
Zodra we het pakket hebben gemaakt, zullen we veel bestanden opmerken die opnieuw kunnen worden gestructureerd. Nadat we alles naar het overeenkomstige pakket hebben verplaatst en het afhankelijkheden hebben we een nieuwe structuur en een schonere grafiek.
Afhankelijkheden van het hoofdpakket verwijderen
Nu ziet onze grafiek er veel beter uit. Het zou geweldig zijn als we alle afhankelijkheden van het rootpakket kunnen verwijderen. Als we deprecated_references.yml in het rootpakket controleren, zullen we zien dat de meeste van hen van test , lib/taken , db en config map. Om deze afhankelijkheden op te lossen, gaan we in elk pakket een testmap maken. Iets als app/pakketten/gebruikers/test. Vervolgens gaan we lib/taken , db en configonder andere mappen van Packwerk analyse omdat die afhankelijkheden niet echt belangrijk zijn in onze analyse en we geen gemakkelijke manier hebben om ze op te lossen. We voegen het volgende toe aan onze pakwerk.yml.
Na het verplaatsen van alle tests uit het rootpakket en het uitsluiten van de mappen uit de analyse, hebben we een nieuwe grafiek zonder rootafhankelijkheden.
Zoals we kunnen zien, hebben we nog steeds circulaire afhankelijkheden ingebruikers , repo's en docs . Hoewel we ze niet hebben opgelost, hebben we nu belangrijke informatie om door te geven. We weten dat elke team die wijzigingen doorvoert in één van die pakketten, zal waarschijnlijk ook wijzigingen moeten doorvoeren in de pakketten met de circulaire afhankelijkheid. Aan de andere kant weten we dat een team kan werken aan github_fetchers alleen, weten welke pakketten die op elk moment wordt beïnvloed door de veranderingen.
Je kunt het eindresultaat van het project vinden hier.
Volgende stap
Als volgende stap zou je constante privacy kunnen afdwingen in elk pakket en alleen de openbare API kunnen vrijgeven die toegankelijk zal zijn vanuit andere pakketten. Je kunt eenvoudig configureren waar je API wordt geplaatst in package.yml.
privacy afdwingen: true
afhankelijkheden afdwingen: waar
openbaar_pad: mijn/aangepast/pad/
Conclusies
Packwerk geeft ons veel informatie over onze applicatie en met die informatie kunnen we beslissingen nemen om de workflow van onze teams te verbeteren. Hoewel het proces lang leek en met veel configuraties, hoeft het niet altijd zo te zijn. We kunnen beginnen met het maken van pakketten alleen voor de nieuwe code die aan onze applicatie wordt toegevoegd en dan geleidelijk modulariseren. Nu kunnen we dus beginnen te praten over geleidelijke modularisatie, een concept dat is geïntroduceerd door Stephan Hagemann. "We kunnen voor het eerst besluiten om te beginnen met het modulariseren van een deel van de code op een aspirationele manier... Dit stelt ons in staat om een geleidelijk uitbreidend ondersteuningssysteem te creëren in de richting van een betere applicatiestructuur".