window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster już istnieje') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Modularyzacja Ruby on Rails za pomocą Packwerk Episode II - The Codest
The Codest
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Branże
    • Fintech i bankowość
    • E-commerce
    • Adtech
    • Healthtech
    • Produkcja
    • Logistyka
    • Motoryzacja
    • IOT
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
Strzałka w tył WSTECZ
2022-01-10
Software Development

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.

struktura pakietu

Jeśli spróbujemy uruchomić serwer, nie uda mu się znaleźć stałych. Dlatego też musimy dodać linię konfiguracji do naszego pliku application.rb

config.paths.add 'app/packages', glob: '*/{*,*/concerns}', eager_load:true

Teraz aplikacja działa, ale nie może znaleźć widoków, więc musimy dodać kolejną linię konfiguracji do naszej aplikacji application_controller.rb

append_view_path(Dir.glob(Rails.root.join('app/packages/*/views')))

Tworzenie pakietów

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

package.yml

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.

# packwerk.yml

load_paths:
.
.
.

# Users
- app/packages/users/controllers
- app/packages/users/models
- app/packages/users/package.yml
- app/packages/users/views

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.

deprecated_references.yml
# deprecated_references.yml

.
.
.

app/packages/repos:
  "::Repo":
    naruszenia:
    - zależność
    pliki:
    - app/packages/users/models/user.rb

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.

wykres bez zaakceptowanych zależności

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.

# app/packages/mail_builders/package.yml

``ruby
enforce_privacy: false
enforce_dependencies: true
dependencies:
- app/packages/docs
- app/packages/issues
- app/packages/repos

Po dodaniu tej konfiguracji, Pocky pokoloruje zaakceptowane zależności na zielono.

graf z zaakceptowanymi zależnościami

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:

- Nie rób nic,

- Zaakceptuj zależności, Scal pakiety,

- Przeprowadzka kod między pakietami,

- Powielanie funkcji, 

- 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:

  1. Przenieś wszystkie pliki i foldery application_ z aplikacji do folderu app/packages/rails.
  2. Utwórzpackage.yml dla pakietu z taką samą konfiguracją jak poprzednie pakiety.
  3. Dodaj wszystkie nowe ścieżki plików do packwerk.yml.
  4. 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.

Struktura pakietu z pakietem szyn
Wykres bez głównych zależności kołowych

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.

exclude:
- "{bin,node_modules,script,tmp,vendor,lib,db,config,perf_scripts}/**/*"
- "lib/tasks/**/*.rake"

Po przeniesieniu wszystkich testów z pakietu root i wykluczeniu folderów z analizy otrzymamy nowy wykres bez zależności root.

Wykres bez zależności głównych

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.

Możesz znaleźć końcowy rezultat projektu tutaj.

Następny krok

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.

enforce_privacy: true
enforce_dependencies: true
public_path: my/custom/path/

Wnioski

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".

Źródła

  1. Stopniowa modularyzacja dla Ruby on Rails - Stephan Hagemann
  2. Wymuszanie modułowości w aplikacjach Rails za pomocą Packwerk
  3. Packwerk Github
  4. Kod źródłowy artykułu
Doradztwo w zakresie rozwoju produktów cyfrowych

Czytaj więcej

GraphQL Ruby. Co z wydajnością?

Szyny i inne środki transportu

Rails Development z TMUX, Vim, Fzf + Ripgrep

Powiązane artykuły

Software Development

Tworzenie przyszłościowych aplikacji internetowych: spostrzeżenia zespołu ekspertów The Codest

Odkryj, w jaki sposób The Codest wyróżnia się w tworzeniu skalowalnych, interaktywnych aplikacji internetowych przy użyciu najnowocześniejszych technologii, zapewniając płynne doświadczenia użytkowników na wszystkich platformach. Dowiedz się, w jaki sposób nasza wiedza napędza transformację cyfrową i biznes...

THEECODEST
Software Development

10 najlepszych firm tworzących oprogramowanie na Łotwie

Dowiedz się więcej o najlepszych łotewskich firmach programistycznych i ich innowacyjnych rozwiązaniach w naszym najnowszym artykule. Odkryj, w jaki sposób ci liderzy technologiczni mogą pomóc w rozwoju Twojej firmy.

thecodest
Rozwiązania dla przedsiębiorstw i scaleupów

Podstawy tworzenia oprogramowania Java: Przewodnik po skutecznym outsourcingu

Zapoznaj się z tym niezbędnym przewodnikiem na temat skutecznego tworzenia oprogramowania Java outsourcing, aby zwiększyć wydajność, uzyskać dostęp do wiedzy specjalistycznej i osiągnąć sukces projektu z The Codest.

thecodest
Software Development

Kompletny przewodnik po outsourcingu w Polsce

Wzrost liczby outsourcing w Polsce jest napędzany przez postęp gospodarczy, edukacyjny i technologiczny, sprzyjający rozwojowi IT i przyjazny klimat dla biznesu.

TheCodest
Rozwiązania dla przedsiębiorstw i scaleupów

Kompletny przewodnik po narzędziach i technikach audytu IT

Audyty IT zapewniają bezpieczne, wydajne i zgodne z przepisami systemy. Dowiedz się więcej o ich znaczeniu, czytając cały artykuł.

The Codest
Jakub Jakubowicz CTO & Współzałożyciel

Subskrybuj naszą bazę wiedzy i bądź na bieżąco!

    O nas

    The Codest - Międzynarodowa firma programistyczna z centrami technologicznymi w Polsce.

    Wielka Brytania - siedziba główna

    • Office 303B, 182-184 High Street North E6 2JA
      Londyn, Anglia

    Polska - lokalne centra technologiczne

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polska

      The Codest

    • Strona główna
    • O nas
    • Nasze Usługi
    • Case Studies
    • Nasze Know How
    • Kariera
    • Słownik

      Nasze Usługi

    • Konsultacje IT
    • Software Development
    • Backend Development
    • Frontend Development
    • Zespoły IT
    • Backend Dev
    • Inżynierowie rozwiązań chmurowych
    • Inżynierowie danych
    • Inne
    • Inżynierowie QA

      Raporty

    • Fakty i mity na temat współpracy z zewnętrznym partnerem programistycznym
    • Z USA do Europy: Dlaczego amerykańskie startupy decydują się na relokację do Europy?
    • Porównanie centrów rozwoju Tech Offshore: Tech Offshore Europa (Polska), ASEAN (Filipiny), Eurazja (Turcja)
    • Jakie są największe wyzwania CTO i CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Warunki korzystania z witryny

    Copyright © 2025 by The Codest. Wszelkie prawa zastrzeżone.

    pl_PLPolish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek pl_PLPolish