Flutter vs. Dart
Většina lidí si Flutter a Dart plete, jako by to bylo totéž, zejména proto, že Dart a Flutter úzce spolupracují při vývoji napříč platformami. Oba jsou nezbytné pro vytváření androidových...
Ve druhém díle našeho seriálu o modularizaci Ruby on Rails s Packwerkem se blíže podíváme na koncept aplikace jako balíčku.
Přístup k modularizaci naší aplikace spočívá v převedení celé aplikace do balíčku.
Nejprve musíme vytvořit app/packages do které umístíme všechny naše balíčky. Abychom naše balíčky oddělili, musíme každou Koncept MVC v jedné složce. Vezmeme-li CodeTriage projekt jako příklad nám poslouží následující obrázek.

Pokud se pokusíme server spustit, nepodaří se nám konstanty najít. Proto musíme přidat řádek konfigurace do našeho application.rb
config.paths.add 'app/packages', glob: '*/{*,*/concerns}', eager_load:true
Nyní aplikace funguje, ale nemůže najít pohledy, takže musíme přidat další řádek konfigurace do naší aplikace. application_controller.rb
append_view_path(Dir.glob(Rails.root.join('app/packages/*/views')))
Naše struktura je připravena, takže nyní můžeme začít vytvářet balíčky. K tomu potřebujeme pouze přidat položkupackage.yml do každé složky s následující konfigurací:
enforce_privacy: false
enforce_dependencies: true

enforce_privacyposkytuje nás možnost izolovat všechny konstanty balíčku a pracovat s veřejným API. Abychom mohli vystavit veřejné konstanty, musíme přidat konstanty do, např. packages/users/app/public.Prozatím nastavíme tuto konfiguraci na hodnotu false.
enforce_dependencies vynutí závislost balíčku a zkontroluje všechny odkazy na konstanty. Pokud závislost není explicitně definována, jedná se o porušení hranice.
Packwerk stanovil kritérium, které musíme dodržovat, abychom měli platný balíčkový systém. Můžeme začít spouštět packwerk validovat v naší konzoli.
Zkontroluje strukturu složek, konfigurace balíčkua automatické načítání mezipaměti cest.
V tuto chvíli naše aplikace není platná a musíme opravit cesty načítání v aplikacipackwerk.yml. K tomu stačí přidat chybějící cesty.
# packwerk.yml
load_paths:
.
.
.
# Uživatelé
- app/packages/users/controllers
- app/packages/users/models
- app/packages/users/package.yml
- app/packages/users/views
V tomto okamžiku jsme připraveni zkontrolovat porušení hranic v naší aplikaci. Pro kontrolu porušení můžeme spustit příkazpackwerk update-deprecations , tento příkaz vygeneruje deprecated_references.yml pro každý balíček. V každém souboru najdeme název balíčku, typ porušení a cestu k souboru. Díky všem těmto informacím víme, kde k porušení dochází, a můžeme se rozhodnout pro jeho řešení.

# deprecated_references.yml
.
.
.
app/packages/repos:
"::Repo":
porušení:
- závislost
soubory:
- app/packages/users/models/user.rb
Na tomto příkladu popíšeme všechny části generovaných informací.
podle Packwerk.
- app/packages/repos - balíček, kde je porušení konstanty
nalezeno.
- ::Repo - cesta k souboru obsahujícímu porušenou konstantu.
- závislost - typ porušení, ať už závislosti, nebo soukromí.
- app/packages/users/models/user.rb - cesta k souboru obsahujícímu porušenou konstantu.
Jako poslední krok v této části nezapomeňte přidat nově vygenerované cesty k souborům do složky packwerk.yml a znovu spustit ověřování.
Se všemi informacemi v souboru package.yml a deprecated_references.ymlpak můžeme
vizualizovat graf závislostí. K tomu potřebujeme přidat další drahokam, v tomto případě použijeme příkaz Pocky.
Běhající hrábě pocky:generate vygenerujeme soubor s názvem packwerk.png kde můžeme vizualizovat náš první graf závislostí.
Po definování všech balíčků bude náš graf vypadat takto.

závislosti již existují, ale neznamená to, že jsou akceptovány systémem Packwerk. Na
přijmout závislost, musíme přidat konfiguraci závislostí do souboru package.yml
v každém balení. Zaměříme se na mail_builders protože se jedná o balíček bez kruhové závislosti. Za zmínku stojí, že Packwerk nám nedovolí přijmout kruhové závislosti.
# app/packages/mail_builders/package.yml
```ruby
enforce_privacy: false
enforce_dependencies: true
dependencies:
- app/packages/docs
- app/packages/issues
- app/packages/repos
Po přidání této konfigurace, Pocky podbarví přijaté závislosti zeleně.

Můžeme odstranit deprecated_references.yml z app/packages/mail_builders a spustitpackwerk update-deprecations znovu. Soubor nebude znovu vygenerován, protože všechny
u tohoto balíčku byla opravena porušení. Důležité je zmínit, že i když nebudeme Graph s přijatými závislostmi
Ruby modularizace v systému Rails pomocí Packwerk akceptovat závislosti, naše aplikace bude stále fungovat jako dříve, ale nyní máme k dispozici více
informace pro rozhodování a refaktorizaci.
V našem předchozím grafu jsme měli mnoho kruhových závislostí, které bylo třeba nějak vyřešit. K tomu máme různé strategie:
- Nedělejte nic,
- Přijmout závislosti, Sloučit balíčky,
- Přesun kód mezi balíčky,
- Duplikovat funkci,
- Proveďte funkci Dependency injection nebo Dependency injection s typováním.
Jedním z problémů je, že abychom mohli provést správný refaktor, musíme znát kódovou základnu. Vzhledem k tomu, že kódovou základnu tohoto projektu neznám, protože jsem ji bral jako příklad, tak z praktických důvodů zvolíme první strategii, tedy nedělat nic. I když se většině refaktoringu vyhneme, chceme pracovat na závislostech v rámci root balíček.
Kořenový balíček obsahuje všechna lepidla z balíčku Rámec Rails, všechny třídy, od kterých dědíme, a zajistit, aby všechny fungovaly společně. Abychom tedy vyřešili kruhové závislosti, vytvoříme v rámci následujících kroků nový balíček s názvem rails:
app/packages/rails.package.yml pro balíček se stejnou konfigurací jako předchozí balíčky.packwerk.yml.app/packages/rails jako závislost na ostatních balíčcích.Po vytvoření balíčku si začneme všímat mnoha souborů, které lze restrukturalizovat. Po přesunutí všeho do příslušného balíčku a přijetí
závislostí získáme novou strukturu a čistší graf.


Nyní náš graf vypadá mnohem lépe, bylo by skvělé, kdybychom mohli odstranit všechny závislosti z kořenového balíčku. Pokud se podíváme do souboru deprecated_references.yml v kořenovém balíčku, zjistíme, že většina z nich pochází z balíčku test , lib/tasks , db a konfigurace
složka. Abychom tyto závislosti vyřešili, vytvoříme v každém balíčku složku pro testování. Mít něco jako app/packages/users/test. Dále vyloučíme lib/tasks , db a konfiguracemezi dalšími složkami z Packwerk analýzu, protože tyto závislosti nejsou v naší analýze důležité a nemáme snadný způsob, jak je vyřešit. Přidáme do našeho systému následující packwerk.yml.
vyloučit:
- "{bin,node_modules,script,tmp,vendor,lib,db,config,perf_scripts}/**/*"
- "lib/tasks/**/*.rake"
Po přesunutí všech testů z kořenového balíčku a vyloučení složek z analýzy získáme nový graf bez kořenových závislostí.

Jak vidíme, stále máme kruhové závislosti v oblastiuživatelé , repozitáře a dokumenty . I když jsme je nevyřešili, máme nyní důležité informace, které můžeme předat. Víme, že každý tým který provede změny v jednom z těchto balíčků, bude pravděpodobně muset provést změny v balíčcích s kruhovou závislostí. Na druhou stranu víme, že tým může pracovat na github_fetchers výhradně znalost balíčků, které jsou
se v každém okamžiku mění.
Konečný výsledek projektu najdete zde.
V dalším kroku byste mohli v každém balíčku zajistit konstantní soukromí a zpřístupnit pouze veřejné rozhraní API, které bude přístupné z jiných balíčků. Můžete snadno nakonfigurovat, kde bude vaše rozhraní API umístěno v části package.yml.
enforce_privacy: true
enforce_dependencies: true
public_path: my/custom/path/
Packwerk nám poskytuje mnoho informací o naší aplikaci a na základě těchto informací můžeme přijímat rozhodnutí, která zlepší pracovní postupy našich týmů. I když se zdálo, že proces je dlouhý a s mnoha konfiguracemi, nemusí tomu tak být vždy. Můžeme začít vytvářet balíčky pouze pro nový kód přidaný do naší aplikace a postupně jej modulovat. Nyní tedy můžeme začít mluvit o postupné modularizaci, což je koncept, který představil Stephan Hagemann "Poprvé se můžeme rozhodnout začít modulovat část kódu aspiračním způsobem... To nám umožňuje vytvářet postupně se rozšiřující systém podpory směrem k lepší struktuře aplikace."

Přečtěte si více
GraphQL Ruby. Jak je to s výkonem?