O projektu

Mou motivací pro práci na tomto projektu bylo mimo jiné bylo naučit se, jak se zorientovat v neznámém kódu většího projektu. Toho jsem chtěl dosáhnout přispěním podstatné změny do některého open-source projektu a díky vedoucímu mé bakalářské práce jsem narazil na webovou aplikaci NetLogo Web.

Rozhodl jsem se pomoci projektu vyřešením již dlouho otevřené „issue“ z repozitáře na GitHubu. To mimo jiné vyžadovalo projednání požadavků se správci projektu, seznámení se s kódem aplikace a provedení vícero re­fak­to­ro­vá­ní, aby následně bylo možné zavést mo­du­lo­vý systém a integrovat bundler do build systému projektu.

Výsledek

Zde je stručné shrnutí výsledků mého úsilí:

  • Změny, které jsem navrhnul již byly začleněny do projektu a jsou jeho pevnou součástí.
  • Kód frontendu projektu má nyní pevnější základy a používá řádný modulový systém.
  • Některé ze změn, které bylo potřeba udělat před zavedením modulového systému (jako například odstranění kruhových závislostí mezi skripty nebo zbavení se desítek glo­bál­ních pro­měn­ných) také přispěly k lepší čitelnosti kódu a lepšímu přehledu o zá­vis­los­tech mezi jednotlivými částmi projektu.
  • Dostal jsem velmi vděčnou odezvu na provedené změny. Níže je citát jednoho ze správců projektu (přeloženo z angličtiny):

🎉 Wow! 🎉

🙇‍♂️ Díky, díky, díky, díky, díky za odeslání tohoto ohromného a neskutečně cenného pull-requestu! 🙇‍♂️

Nesmírně si vážím a cením toho, že jsi si dal tu práci a udělal věci, které jsem už před lety měl udělat sám! Mám z toho velkou radost a technické základy tohoto projektu jsou díky tomu mnohem legitimnější. Děkuju!

Upřímně řečeno, i když mám několik drobných výtek, tak mi tento pull-request přijde nesmírně kvalitní. Při re­fak­to­ro­vá­ní jsi na téměř každém podstatném místě jsi udělal to, co je dle mého ná­zo­ru nej­ro­zum­něj­ší rozhodnutí. Přijde mi to opravdu obdivuhodné! 👏

- Jason B., správce NetLogo Web
Originální citát v angličtině

🎉 Wow! 🎉

🙇‍♂️ Thank you, thank you, thank you, thank you, thank you for submitting this enormous and incredibly valuable pull request! 🙇‍♂️

I have an immense amount of respect and appreciation for going through all the trouble to do this, and doing things that I should have done years ago, myself. This is so exciting, and makes the technical foundations of this project feel so much more legitimate. Thank you!

Honestly, looking this over, while I have a number of small quibbles, I think this PR is of incredibly high quality. At nearly every important crossroads, you made what I consider to be the most intelligent refactoring decision. I find it really impressive! 👏

- Jason B., maintainer of NetLogo Web

Můj přístup

Seznámení se s projektem

Prvním krokem bylo otevřít diskusi se správci projektu a zjistit, jaké jsou jejich představy ohledně modulového systému a bundleru a jestli by stáli o to, abych se tohoto úkolu ujal.

Dalším krokem bylo seznámit se s kódem projektu. V té době projekt ještě nepoužíval žádný modulový systém a funkcionalita z každého souboru byla zpřístupněna formou globálních proměnných. Proto jsem se rozhodl zmapovat projekt vytvořením grafu zná­zor­ňu­jí­cí­ho zá­vis­los­ti mezi jednotlivými skripty. Bohužel se mi nepodařilo vyhrabat původní graf, ale níže je alespoň verze, která již zahrnuje některé provedené změny (například už neobsahuje kruhové závislosti mezi soubory).

Graf závislostí mezi soubory.
Graf závislostí mezi front­en­do­vý­mi skripty (po provedení některých změn).

V rámci seznamování s kódem jsem se také musel naučit číst a do určité míry i psát kód v CoffeeScriptu a Scale, což byly hlavní programovací jazyky používané v projektu. Ale ob­zvláš­tě práce s Cof­fee­Script­em mi nedělala problémy, protože jde v podstatě pouze o al­ter­nativ­ní syntaxi JavaScriptu a mohl jsem se většinou spolehnout na své existující znalosti.

Rozsáhlé re­fak­to­ro­vá­ní

Poté, co jsem se seznámil s projektem, byl čas pustit se do re­fak­to­ro­vá­ní! Protože cílem bylo použít na frontendu ECMAScript moduly s příkazy importexport, tak bylo nutné, aby kód splňoval požadavky na tzv. striktní režim JavaScriptu.

Kvůli tomu bylo mimo jiné potřeba zbavit se kruhových závislostí, protože cyklické importy mezi soubory nefungují příliš dobře v kombinaci s ECMAScript moduly. Rozpletení některých kru­ho­vých závislostí vyžadovalo trochu důvtipu a použití několika různých strategií. V něk­te­rých pří­pa­dech například pomohlo rozdělit modul s více třídami nebo funkcemi do několika sa­mo­stat­ných souborů, jindy jsem zase problém vyřešil předáním závislosti přes parametr místo jejího přímého importu.

Po splnění těchto předpokladů bylo konečně možné nahradit desítky (ne-li přes stovku) globál­ních proměnných příkazy exportimport. Kromě front­en­do­vých skriptů bylo také potřeba udělat několik změn v dalších částech projektu, jako například v backendu aplikace nebo v kódu pro testy.

Integrování bundleru

I když nebylo úplně triviální zorientovat se v kódu projektu provádět rozsáhlá re­fak­to­ro­vá­ní, tak nejtěžší částí pro mě jednoznačně byla práce s build systémem projektu, který používá nástroj SBT. (Domnívám se, že některé z mých obtíží pramenily z velkého množství vrstev abstrakce, z nichž většina pro mě byla nová: knihovna sbt-web nad build systémem SBT s něko­li­ka vlast­ní­mi vrstvami abstrakce a dále jazyk Scala, který běží na JVM a vypůjčuje si některé kon­cep­ty a nástroje z ekosystému Javy.)

Po delší době strávené čtením kódu knihovny sbt-web a jiných projektů po­u­ží­va­jí­cích SBT (dokumentace SBT a sbt-web bohužel nebyla dostačující pro vyřešení některých po­kro­či­lej­ších problémů), se mi nakonec podařilo úspěšně do build procesu integrovat bundler Rollup. Po překonání problémů se SBT bylo již hračkou na­kon­fi­gu­ro­vat Rollup pro bundlování a mi­ni­fi­ka­ci front­en­do­vé­ho kódu.

Dokončení projektu

Předtím než se změny, které jsem udělal mohly stát součástí projektu, zbývalo ještě udělat několik věcí. Zdo­ku­men­to­val jsem všechny provedené změny a tam, kde to bylo potřeba popsal podstatné detaily a důvody, které vedly k použití určitého řešení. Dále jsem podrobněji popsal, jak funguje nový build proces, se zaměřením zejména na bundling pomocí Rollupu, jelikož správci projektu s Rollupem ještě neměli zkušenosti.

Poté nastal čas odeslat výsledek práce vytvořením pull-requestu (požadavku na přijetí změn). Celkový ohlas od správců projektu byl velmi pozitivní a vděčný. Po vyjasnění ně­ko­li­ka detailů a opravě drobnějších problémů objevených při revizi kódu byly změny akceptovány a staly se součástí reálného projektu.

Co jsem se naučil

I když jsem v některých fázích projektu pochyboval, zda se mi ho podaří úspěšně dokončit, jsem velmi rád, že jsem se rozhodl se do této výzvy pustit a mnoho jsem se díky tomu naučil.

Vyzkoušel jsem si, jak se rychle zorientovat v neznámém kódu většího projektu, který navíc používal některé programovací jazyky a nástroje, které jsem předtím neznal.

Také jsem se výrazně zlepšil v používání verzovacího systému Git, který jsem při práci hojně využíval – bez používání „větví“ (branches) a stashe pro zachování přehledu o rozpracované práci nebo (in­ter­ak­tiv­ní­ho) rebase na zpřehlednění historie commitů by to nešlo. Jednalo se také o můj první větší příspěvek do open-source projektu.

Dále bylo potřeba mít dost vytrvalosti, když jsem se potýkal s build systémem aplikace. Díky tomu, že u některých nástrojů ne­vy­sta­čo­va­la jejich dokumentace, byl jsem nucen naučit se, jak si najít si potřebné informace přímo ve zdrojovém kódu daného nástroje/knihovny.

Závěrem bych chtěl poděkovat správcům projektu NetLogo Web za jejich vstřícnost a uži­teč­nou zpětnou vazbu při revizi mého kódu.