Modularyzacja Ruby on Rails za pomocą Packwerk Episode II
Nicolas Nisoria
W drugim odcinku naszej modularyzacji Ruby on Rails z Packwerk przyjrzymy się bliżej koncepcji aplikacji jako pakietu.
Aplikacja jako pakiet
Podejście do modularyzacji naszej aplikacji polega na przekształceniu całej aplikacji w pakiet.
Tworzenie struktury
Najpierw musimy utworzyć app/packages w którym umieścimy wszystkie nasze pakiety. Aby odizolować nasze pakiety, musimy oddzielić każdy z nich Koncepcja MVC w jednym folderze. Biorąc CodeTriage projekt Jako przykład otrzymamy coś takiego jak na poniższym obrazku.
Jeśli spróbujemy uruchomić serwer, nie uda mu się znaleźć stałych. Dlatego też musimy dodać linię konfiguracji do naszego pliku application.rb
Nasza struktura jest gotowa, więc teraz możemy rozpocząć tworzenie pakietów. Aby to zrobić, musimy tylko dodać plikpackage.yml do każdego folderu z następującą konfiguracją:
enforce_privacy: false
enforce_dependencies: true
enforce_privacydaje nam możliwość odizolowania wszystkich stałych pakietu i pracy z publicznym API. Aby wyeksponować stałe publiczne, musimy dodać stałe w, na przykład packages/users/app/public.Na razie ustawimy tę konfigurację na fałszywy.
enforce_dependencies wymusi zależność pakietu i sprawdzi wszystkie stałe odniesienia. Jeśli zależność nie jest wyraźnie zdefiniowana, będzie to naruszenie granicy.
Weryfikacja systemu pakietów
Packwerk ustanowiła kryterium, którego musimy przestrzegać, aby mieć prawidłowy system pakietów. Możemy rozpocząć uruchamianie walidacja packwerk w naszej konsoli.
Spowoduje to sprawdzenie struktury folderów, konfiguracja pakietui automatyczne ładowanie pamięci podręcznej ścieżki.
W tej chwili nasza aplikacja nie jest prawidłowa i musimy naprawić ścieżki ładowania wpackwerk.yml. Aby to zrobić, musimy tylko dodać brakujące ścieżki.
W tym momencie jesteśmy gotowi do sprawdzenia naruszeń granic w naszej aplikacji. Aby sprawdzić naruszenia, możemy uruchomićpackwerk update-deprecations to polecenie wygeneruje deprecated_references.yml dla każdego pakietu. W każdym pliku znajdziemy nazwę pakietu, typ naruszenia i ścieżkę pliku. Dzięki tym wszystkim informacjom wiemy, gdzie występuje naruszenie i możemy podjąć decyzję o jego rozwiązaniu.
Biorąc przykład, opiszemy każdą część wygenerowanych informacji przez Packwerk.
– app/packages/repos - pakiet, w którym stałym naruszeniem jest znaleziono.
– ::Repo - ścieżka do pliku zawierającego naruszoną stałą.
– zależność - rodzaj naruszenia, zależność lub prywatność.
– app/packages/users/models/user.rb - ścieżka do pliku zawierającego naruszoną stałą.
Ostatnim krokiem w tej sekcji jest dodanie nowo wygenerowanych ścieżek plików do sekcji packwerk.yml i ponownie uruchomić walidacje.
Wizualizacja zależności
Ze wszystkimi informacjami w package.yml i deprecated_references.ymlmożemy wtedy wizualizować wykres zależności. Aby to zrobić, musimy dodać kolejny klejnot, w tym przypadku użyjemy Pocky.
Zgrabiarka pocky:generate wygenerujemy plik o nazwie packwerk.png gdzie możemy zwizualizować nasz pierwszy wykres zależności.
Po zdefiniowaniu wszystkich pakietów nasz wykres będzie wyglądał następująco.
zależności już istnieją, ale nie oznacza to, że są one akceptowane przez Packwerk. Do zaakceptować zależność, musimy dodać konfigurację zależności do package.yml w każdym pakiecie. Skupimy się na mail_builders ponieważ jest to pakiet bez zależności kołowych. Warto wspomnieć, że Packwerk nie pozwoli nam zaakceptować zależności kołowych.
Po dodaniu tej konfiguracji, Pocky pokoloruje zaakceptowane zależności na zielono.
Możemy usunąć deprecated_references.yml z app/packages/mail_builders i uruchomić packwerk update-deprecations ponownie. Plik nie zostanie wygenerowany ponownie, ponieważ wszystkie naruszenia zostały naprawione dla tego pakietu. Ważne jest, aby wspomnieć, że nawet jeśli nie Graph z zaakceptowanymi zależnościami
Modularyzacja Ruby on Rails za pomocą Packwerk zaakceptować zależności, nasza aplikacja nadal będzie działać jak poprzednio, ale teraz mamy więcej informacje do podejmowania decyzji i refaktoryzacji.
Usunięcie zależności kołowych
W naszym poprzednim wykresie mieliśmy wiele zależności kołowych, które trzeba było jakoś rozwiązać. Mamy na to różne strategie:
- Wykonaj wstrzykiwanie zależności lub wstrzykiwanie zależności z typowaniem.
Jedną z kwestii jest to, że aby wykonać właściwy refaktoring, musimy znać bazę kodu. Nie jestem zaznajomiony z bazą kodu tego projektu, ponieważ wziąłem go jako przykład, więc ze względów praktycznych wybierzemy pierwszą strategię, nie rób nic. Nawet jeśli unikniemy większości refaktoryzacji, chcemy popracować nad zależnościami w korzeń pakiet.
Pakiet główny zawiera wszystkie klejenia z Framework RailsWszystkie klasy, po których dziedziczymy, będą ze sobą współpracować. Tak więc, aby rozwiązać problem zależności kołowych, utworzymy nowy pakiet o nazwie rails w następujących krokach:
Przenieś wszystkie pliki i foldery application_ z aplikacji do folderu app/packages/rails.
Utwórzpackage.yml dla pakietu z taką samą konfiguracją jak poprzednie pakiety.
Dodaj wszystkie nowe ścieżki plików do packwerk.yml.
Dodaj app/packages/rails jako zależność od reszty pakietów.
Po utworzeniu pakietu zaczniemy zauważać wiele plików, które można przeorganizować. Po przeniesieniu wszystkiego do odpowiedniego pakietu i zaakceptowaniu będziemy mieli nową strukturę i czystszy wykres.
Usunięcie zależności z pakietu głównego
Teraz nasz wykres wygląda znacznie lepiej, byłoby świetnie, gdybyśmy mogli usunąć wszystkie zależności z pakietu root. Jeśli sprawdzimy deprecated_references.yml w pakiecie głównym, zauważymy, że większość z nich pochodzi z test , lib/tasks , db i konfiguracja folder. Aby rozwiązać te zależności, utworzymy folder testowy w każdym pakiecie. Mając coś takiego jak app/packages/users/test. Następnie zamierzamy wykluczyć lib/tasks , db i konfiguracjawśród innych folderów z Packwerk ponieważ te zależności nie są tak naprawdę ważne w naszej analizie i nie mamy łatwego sposobu na ich rozwiązanie. Dodamy następujące elementy do naszego packwerk.yml.
Po przeniesieniu wszystkich testów z pakietu root i wykluczeniu folderów z analizy otrzymamy nowy wykres bez zależności root.
Jak widzimy, wciąż mamy zależności kołowe wużytkownicy , repozytoria oraz dokumenty . Chociaż ich nie rozwiązaliśmy, mamy teraz ważne informacje do przekazania. Wiemy, że każdy zespół który wprowadza zmiany w jednym z tych pakietów, prawdopodobnie będzie musiał wprowadzić zmiany w pakietach z zależnością cyrkularną. Z drugiej strony wiemy, że zespół może pracować nad github_fetchers wyłącznie wiedząc, jakie pakiety są ulegając zmianom w każdej chwili.
Następnym krokiem może być wymuszenie stałej prywatności w każdym pakiecie i ujawnienie tylko publicznego interfejsu API, który będzie dostępny z innych pakietów. Możesz łatwo skonfigurować, gdzie twój interfejs API zostanie umieszczony w package.yml.
Packwerk daje nam wiele informacji o naszej aplikacji i dzięki tym informacjom możemy podejmować decyzje mające na celu poprawę przepływu pracy naszych zespołów. Chociaż proces wydawał się długi i wymagał wielu konfiguracji, nie musi tak być zawsze. Możemy zacząć tworzyć pakiety tylko dla nowego kodu dodanego do naszej aplikacji, a następnie stopniowo modularyzować. Teraz możemy zacząć mówić o stopniowej modularyzacji, która jest koncepcją wprowadzoną przez Stephana Hagemanna. "Po raz pierwszy możemy zdecydować się na rozpoczęcie modularyzacji części kodu w aspiracyjny sposób... Pozwala nam to stworzyć stopniowo rozwijający się system wsparcia w kierunku lepszej struktury aplikacji".