Modulární webové aplikace s minimem ruční práce

Jak se javascriptový ekosystém bouřlivě vyvíjí, vzniká stále více nástrojů pro pohodlnější a robustnější vývoj webových aplikací. Proklestit se tou záplavou novinek není snadné, a proto jsem se rozhodl napsat další článek o několika výtečných exemplářích, které nám open source komunita připravila.

Jak asi už víte, můj pohled na vývoj webových aplikací se jmenuje github.com/Steida/este. Rozhodně nechci tvrdit, že jde o jediné správné řešení. Každý dobrý framework v něčem vyniká, ať už se jedná o Angular, Backbone nebo Dart. Pro mne je rozhodující statická analýza, robustnost, rozsáhlost a čistota návrhu Closure Library, a samozřejmě bezkonkurenční Closure Compiler. Pro někoho jiného to bude zas snadná manipulace s DOM (Angular), relativní jednoduchost, hodně příkladů a stabilita (Backbone), nebo sázka na budoucnost a platformu, navrženou od základů znova, která možná uspěje a možná ne (Dart).

Tento článek je výsledkem mého refactoringu Este. První verze Este byla monolitická knihovna, se všemi závislostmi v repository, a všemi build tasky ručně scriptovanými v Node.js. Fungovalo to, ale spokojený jsem s tím rozhodně nebyl. Důvod, proč jsem pro scriptování použil Node.js a ne třeba Bash, byl zřejmý. Chtěl jsem, aby Este fungovalo na všech platformách, a v jazyce, který jeho budoucí uživatelé už znají.

Package Managment

Package management je něco, co je ve vyzrálejších ekosystémech dávno běžné, a co se do světů PHP a .NET dostalo až v nedávné době. Composer a NuGet totálně změnily způsob, jakým programátoři skládají své aplikace, a těžko si představit, kde by ty platformy byly, nebýt šikovných jedinců – nadšenců. Ještě ne zcela dávno, pokud chtěl programátor do své aplikace zaimplementovat moduly třetích stran, lovil je a stahoval po všech čertech. Vzpomínám si, jak se D.G. rozčiloval, že na stránce learnboost.github.com/stylus nemůže najít odkaz na download, případně jak už nevím kdo na Twitteru, že si nějak nedovede vybavit, kterak řídil zavislosti před PHP Composerem (= nijak).

Já jsem paradoxně řešil podobný problém pro Este. Paradoxně proto, že platforma Node.js dostala do vínku mocný NPM. Ten však je určen pro serverový JavaScript. Este má ale mnoho klientských závislostí a já dumal, jak ty organizovat. Někdo mi radil Git submodules, další, ať ohnu NPM. Naštěstí však Twitter přišel s nástrojem, který přesně splňoval moje požadavky.

Bower

Bower je jednoduchý. Jedním souborem ve formátu json definujete závislosti aplikace. Bower podporuje různé endpointy, včetně gitu nebo vlastního adresáře. Endpointy mohou a měly by být sémanticky verzované, což umožňuje fixovat závislosti na konkrétní verze. Příkazem bower install se všechny závislosti nainstalují. Adresář s moduly třetích stran (jQuery, animate.css atd.) pak nastavíte tak, aby jej váš verzovací systém ignoroval. Commitujete pouze konfigurační soubor. Výsledkem je, že vaše repository zbytečně nebobtná, a že nové verze závislostí nešpiní commit log. Ten obsahuje pouze seznam změn vaší aplikace.

Bower není jediný, existují další například Jam.js nebo Volo.js. Oproti Boweru nabízejí další funkce, jejich budoucnost však nevidím růžově, vzhledem k projektu Component, o kterém si něco řekneme za chvíli. Bower se soustředí na jednu věc, a tu dělá dobře. Není důvod, abych zde popisoval vše, co Bower umí, když už je to lépe popsáno zde a zde.

Jmenuji se Daniel Steigerwald a pomáhám firmám i jednotlivcům s vývojem webových aplikací. Pořádám školení, která si můžete objednat na javascript-skoleni.cz. Pokud máte dotazy, napište mi.

Build tools

Když už máme závislosti stažené, a k tomu vlastní, nastává situace, kdy potřebujeme všechny části nějak spojit a připravit pro nasazení. Zdánlivě triviální úkol se pro větší aplikaci záhy rozpadne do nesčetných tasků. Na Macu nebo Linuxu je k dispozici bash a make, pro Windows třeba PowerShell, ale to pro moderní dev stack nestačí nehledě na to, že tyto technologie také nejsou multiplatformní. Namátkou:

  • transpilace stylů a JavaScriptu
  • minimalizace stylů a JavaScriptu
  • spouštění testů
  • lokalizace
  • kompilace klientských šablon

V Este jsem původně aplikaci sestavoval pomocí scriptů psaných v Node.js, ale ani to nebylo to pravé. Naštěstí se však objevil Grunt.js.

Grunt.js

Z počátku nic moc nástroj, který ovšem open source komunita časem vybrousila k výborné použitelnosti. Počkal jsem si na verzi 0.4.0, která už má stabilní a dobře navržené api, a všechny dřívější tasky Este rozpustil do Grunt pluginů. Některé již existovaly, a některé jsem si napsal sám. Těch existujících jsou stovky. Grunt.js je napsaný nad Node.js, je tedy také multiplatformní. Grunt umí mnoho věcí, opět zde nemá smysl opakovat manuál, takže více zde: gruntjs.com/getting-started. Grunt není jediný build nástroj pro JavaScript, ale je zdaleka nejrozšířenější, a většina velkých hráčů na něj přešla.

Module loaders

Zde maličko odbočím. Asi jste si všimli, že mnoho odborných výrazů nepřekládám. Za prvé je to ztráta času, za druhé české ekvivalenty neexistují a pokud ano, tahají profesionála za ucho. Třeba plugin by se sice dal přeložit jako „vložka“, a možná by se takový překlad i ujal…, ale jak říkám, takové překlady jsou ztrátou času, stejně jako čtení přeložených knih o programování. Jděte raději rovnou ke zdroji.

K čemu tedy jsou module loaders? Stejně jako JavaScript nemá klíčové slovo pro jmenné prostory, třídy, volání přepsané metody, nemá ani klíčové slovo pro vyjádření závislostí v kódu. Respektive, Node.js takové klíčové slovo má, require, dle specifikace Common.js. require je synchronní a v serverovém JavaScriptu funguje výborně. Klientský JavaScript v prohlížeči však nativně nic takového nepodporuje. Proto má skoro každý JS framework vlastní implementaci založenou buď na AMD, nebo na nějaké vlastní verzi Common.js, nebo úplně proprietární technologii. Mít tolik „standardů“ není samozřejmě pro ekosystém zdravé. Mimochodem, zrovna tohle jsem při Este refactoringu neřešil, protože Google Closure Tools mají vlastní elegatní řešení podobné Common.js už léta.

Implementací existuje jako obvykle v JS světě celá řada, a dlouho jsem doporučoval Require,js, protože byl nejrozšířenější. Require.js ale vychází z AMD a má všechny jeho neduhy. Bylo jasné, že musí vzniknout principiálně lepší řešení. Vzniklo, opět díky open source, respektive geniálnímu TJ Holowaychukovi. Nejdříve článek, jak by to mohlo vypadat. Chvíli poté funkční implementace.

Component

Component je zatím velmi mladá technologie, ale už teď plně použitelná a se stovkami existujících pluginů. Čím se Component odlišuje, a proč ho považuji za přelomový? Component používá CommonJS syntax. Component kombinuje module loader a package manager. Ten jako repository používá přímo Github. Component chytře vyhodnocuje závislosti na serveru, a prohlížeč tak dostane pouze výsledný script. Tohle umožňuje nebývalou granularitu závislostí. Package může být klidně i jedna jediná funkce. Konečně něco, co se blíží Closure Compileru.

Být autorem Angularu, Backbone nebo jQuery knihoven, další verzi bych psal již nad Component. Z jedné monolitické knihovny bych udělal mnoho drobných. Žádné hloupé klikací konfigurátory downloadu (jQuery 2.0), žádné proprietární játaky AMD a CommonJS variace. Component je tady, a nikdo nic lepšího hned tak nevymyslí.

Závěr

Vývoj JavaScriptové aplikace si bez Boweru a Gruntu už nedovedu představit. Component je velmi zajímavý, nicméně já moc často ekosystém Closure Tools opouštět nemusím. Pro ty, co ale Closure Tools nepoužívají, je Component jasná volba. Pokud máte otázky, ptejte se v diskusi, nebo přijdťe na javascript-skoleni.cz

Související

Independent software gardener, libertarian, web applications consultant and trainer. Google Developer Expert since 2012.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 9

Přehled komentářů

Čelo component
Radek Miček Statická analýza?
Daniel Steigerwald Re: Statická analýza?
Radek Miček Re: Statická analýza?
Pavel Dolezal co je to
Daniel Steigerwald Re: co je to
Martin Hassman Re: co je to
Zbynek Component
tacoberu Re: Component
Zdroj: https://www.zdrojak.cz/?p=7545