Bylo nebylo…
Začalo to na MVP Summitu v listopadu 2014, kde začalo být tak nějak jasné, že Microsoft dále nebude pokračovat ve vývoji ASP.NET Web Forms a že ta technologie časem umře. Tou dobou jsme si již hráli s Knockout JS a v praxi si na několika projektech ověřili, že je to pro naše větší projekty nepraktické. Ne kvůli Knockoutu samotnému, úplně stejné by to bylo s Angularem nebo Reactem. Ale proto, že to jako celek smrdělo.
Potíž byla v tom, že používat javascriptový klientský framework znamená naučit se 50 nových knihoven a toolů, což je pro ne úplně zkušené vývojáře stopka. Dále to znamená, že si musíme napsat spoustu infrastruktury sami, protože na to neexistuje vhodná knihovna, anebo jich existuje 20 a researchem, která se vám bude nejlíp hodit, zaberete víc času, než když si to napíšete sami. V neposlední řadě to znamená psát značné množství javascriptového kódu, který dohromady nic nedělá, jen vezme data odněkud (např. z REST API) a nacpe je někam (do view) anebo naopak.
Na pár projektech jsme to zkusili a přitom jsme museli řešit desítky různých drobných technikálií, jako třeba nějaký unifikovaný mechanismus pro sortování, řazení a filtrování, abychom nemuseli v každé Web API pro tohle metodě přidávat nějaký parametr atd. OData jsou omezená a pro naše účely nevyhovovala, a tak jsme dělali vlastní řešení, což se nám moc nelíbilo.
Nebo jak rozumně provádět validaci, když část validační logiky nelze udělat na klientovi a musí se ověřit na serveru, ale zároveň si nějak na klienta potřebujete přenést informace o tom, která políčka selhala, a obarvit je úplně stejně, jako kdyby validace selhala na klientovi. Jde to, ale musíte si to napsat sami.
Nebo třeba hloupé zformátování data na klientovi tak, aby vypadalo stejně jako v PDF, které se generuje na serveru… Existují na to spousty knihoven, ale než je všechny projdete, vyzkoušíte, zjistíte, jestli se nehádají mezi sebou, jestli opravdu dělají to, co píší na jejich webu, a jestli nejsou zabugované a umí správně formáty, které potřebujete, tak to máte sami napsané třikrát. Kapitolou samu pro sebe je konverze lokálního času na UTC a obecně objekt Date v javascriptu, to je teprve skutečné peklo.
Pro typ aplikací, které píšeme, se zkrátka žádná kombinace javascriptových nástrojů a MVC nebo Web API neosvědčila – ne, že by to v tom nešlo napsat, ale bylo to pracné a spoustu věcí jsme si museli psát sami. Logicky jsem se tedy začal poohlížet po nějakém .NETovém stacku, který by řešil naše problémy. Chtěl jsem něco, co by mi ideálně javascriptovou část vygenerovalo, protože zbavit se .NETu na serveru ve prospěch třeba Node.js by bylo mnohem pracnější, náročnější na naučení, a… prostě nemám rád Javascript, protože je to debilně navržený jazyk, kde na každé uprdnutí potřebujete nějakou knihovnu.
Začali jsme s jakousi knihovnou, která uměla C# třídy překládat na typescriptové interfaces, pak jsme si napsali vlastní generátor Knockoutových viewmodelů, protože jsme potřebovali víc, než uměla ta knihovna, ale pořád to nebylo ono. A pak mě napadlo vzít ASP.NET Web Forms, ale místo plných HTTP POSTů použít AJAX a místo kryptického skrytého pole __VIEWSTATE přenášet jenom serializovaný JSON viewmodel z Knockoutu (resp. jen tu jeho část, která je potřeba). Celé to trochu zmodernizovat, postavit to nad MVVM (protože Knockout je taky MVVM) a vyčistit od zbytečností. Doplnit věci, které mi tam chyběly (podpora IoC/DI, data-binding na celé stránce a ne jen tam, kde se volá DataBind, nebo třeba podpora Single Page aplikací), hlavně aby v tom šly rozumně psát komponenty, a nápad byl na světě.
Da path
Dnes je to zhruba rok, co jsme na DotVVM začali pořádně pracovat. Do té doby jsem měl jen prototyp zpatlaný během týdne, kdy jsem se nudil na nějaké konferenci. Zapojil jsem do toho několik lidí z mé firmy RIGANTI, začali jsme pracovat na frameworku a implementovat do něj funkce, které byly potřeba, a samozřejmě to testovat.
Mezitím se DotVVM začalo používat na projektech, které vyvíjíme pro naše zákazníky – největší, na kterém nám DotVVM běží, je už pořádně velký, strávilo se na něm už asi 6 tisíc hodin a nebýt DotVVM, bylo by to mnohem víc, a to i přes to, že jsme hlavně ze začátku podstatnou část dne místo vývoje aplikace samotné hledali, reprodukovali a opravovali bugy ve frameworku a dopisovali chybějící testy. Celkem u nás ve firmě běží v DotVVM už asi 10 aplikací, mimo jiné web dotNETcollege, a pracujeme na dalších a velmi zajímavých.
Začali jsme také implementovat DotVVM komponenty pro Bootstrap – máme kompletně owrapované všechny widgety z Bootstrapu 3. Současně jsme implementovali i wrappery nad Kendo UI, nicméně ty jsme museli pozastavit, jednak kvůli nedostatku času, a jednak kvůli tomu, že se ukázalo, že Kendo je velmi zabugované a že kdybychom si to napsali sami, bylo by to jednodušší – ten jejich grid je hydra, kterou jsme s velkými obtížemi ohnuli pro použití v DotVVM, nicméně věci jako inline editace, která by se integrovala s naší validací, narazily na různé podivnosti a dost značná omezení Kendo Gridu. Jednodušší komponenty napojit šly a pořád je v kurzu možnost, že bychom udělali wrappery alespoň nad Kendo Core, které je open source a zdarma.
Největší challenge byla extension pro Visual Studio. Většina magie v DotVVM se odehrává v našem vlastním formátu DOTHTML, což je klasický HTML soubor, který může obsahovat direktivy (několik řádků na začátku souboru), serverové komponenty (např. <dot:TextBox … />) a data-binding (<a href=”{value: Url}”>…</a>).
HTML editor ve Visual Studiu je rozšiřitelný a není tak těžké doplnit podporu pro vlastní elementy nebo jejich atributy. Dokonce tak nějak v Microsoftu počítali i s věcmi, které potřebujeme my, nicméně potíž je v tom, že dokumentace k tomu neexistuje, takže jsme strávili stovky hodin v Reflectoru a zkoumali, jak celý HTML editor funguje. Spoustu věcí jsme také opsali z Web Essentials, které jsou open source. Potkali jsme se s řadou situací, které rozhodně řešily pouze jednotky lidí na světě, a bylo to místy poučné, místy vtipné, místy šílené a místy úplně zvyjebané (snažil jsem se najít slušnější slovo, ale pro daný účel žádné takové neexistuje). Velký dík a můj neskonalý obdiv má naše Rigantí Black Magic Department, jehož členy jsou Standa Lukeš a Milan Mikuš.
Vzhledem k tomu, že extension je hodně složitá, museli jsme si napsat i vlastní framework pro její testování (přes HTTP jí posíláme commandy a ona je ve Visual Studiu pouští a kontroluje, co se děje).
Abychom mohli celý framework rozumně udržovat, museli jsme napsat stovky testů (včetně Seleniových UI testů, ty jsou velmi důležité) a vím jistě, že ještě několik tisíc nám jich schází. Museli jsme si napsat také vlastní framework nad Seleniem, aby se nám snadněji používalo a aby umělo testy pouštět rychleji a nepouštělo novou instanci browseru pro každý test. Aktuálně DotVVM testujeme v IE 11, posledním Firefoxu a Chrome, a testy pouštíme paralelně, což trvá asi 20 minut – předtím, než jsme vymysleli fast mode, to trvalo skoro 2 hodiny, což bylo neúnosné.
Budeme muset rozjet víc agentů a testovat různé prohlížeče, včetně mobilních, už máme zjištěno, jak Selenium používat proti BrowserStacku, ale den má jen 24 hodin a značnou část ho musíte obětovat něčemu jinému.
Verze 1.0
Světlem na konci tunelu byla konference Build, kde měl mít Roman Jašek krátkou prezentaci nějakého projektu. Vzhledem k tomu, že v Riganti řídí největší projekt na DotVVM postavený, logicky jsme na Buildu u stánku Microsoft Student Partners prezentovali DotVVM.
Natiskli jsme letáčky, vyrobili trička, a dnes ráno mi shodou okolností v mailu přistála gratulace a poděkování od jednoho spokojeného zákazníka, že už to začali používat a že se jim to moc líbí. Jak jsem předpokládal, ve tři ráno jsme udělali release na Nuget, nasadili web, zaklapli notebook a odjeli na letiště – stihlo se to na poslední chvíli.
Aktuální verze je 1.0 BETA, od jejího vydání jsme objevili ještě několik bugů, které opravujeme a zanedlouho vydáme RC. Kromě toho jsme do prodeje vypustili extension pro Visual Studio a komponenty pro Bootstrap.
Připravujeme free verzi naší VS extension, pokud si s DotVVM chcete pohrát, musíte si aktuálně stáhnout 30denní trial verzi.
Zajímá vás to? Chcete se zapojit?
Naprogramovat to bylo snadné. Teď přijde teprve ta pravá fuška, protože o tom budu muset přednášet, psát články, nahrávat videa, vysvětlovat, k čemu to je, v čem to pomůže, že to může ušetřit peníze při vývoji aplikací atd.
V české republice budeme v nejbližší době dělat 2 přednášky a hackathon. Pokud vás DotVVM zajímá, přijďte se podívat.
Doporučuju přijít hlavně na ten hackathon, bude tam víc lidí z DotVVM týmu, takže si bude možné o DotVVM popovídat, budete se moci zeptat na cokoliv a pobavit se s námi o tom, co byste v DotVVM chtěli, co vám tam chybí, nebo co se vám nelíbí.
Jinak pokud myslíte, že by vás práce na DotVVM bavila, tak vězte, že v RIGANTI neustále hledáme schopné lidi. Jednak na vývoj frameworku nebo čehokoliv, co s tím souvisí, a druhak na projekty, kde se DotVVM používá (což jsou už skoro všechny).
Co dál
Mám milion nápadů, co by se s DotVVM dalo dělat. Potřebujeme to naportovat na .NET Core, potřebujeme to umět zahostovat v rámci univerzální Windows aplikace a umožnit napsat v DotVVM univerzální appku. Hodilo by se rozběhnout to i pomocí Xamarinu, abychom v tom mohli psát jednoduché multiplatformní webové aplikace. Když může PhoneGap, proč ne my, a bez psaní javascriptu.
Dál by se mi líbil nástroj, který by uměl projít DOTHTML soubor, najít v něm komponenty, do kterých se dá psát a klikat, a vygenerovat z toho helper třídu pro Selenium, kterou půjde snadno použít pro psaní UI testů. Pro stránku, kde budou dva TextBoxy s bindingy na FirstName a LastName, a tlačítko volající metodu Login, by to vygenerovalo třídu, která by se používala takto:
var test = new LoginTestClass();
test.FirstNameTextBox.Type("Tomáš");
test.LastNameTextBox.Type("Herceg");
test.LoginButton.Click();
Dále by se mi líbilo doplnit do naší Visual Studio extension spoustu funkcí, například možnost automatického konvertování <input type=”text”> na naše <dot:TextBox /> atd., což by pomohlo ve chvíli, kdy dostanete nakódované HTML od grafika, který DotVVM nezná. Nebo nějaký pěkný scaffolding pro GridView, více refactorovacích nástrojů, design time error checking pravidel atd.
Na dobrou noc
Když jsem se nedávno podíval, kolik mě DotVVM stálo, a započítal, kolik jsem mohl vydělat, kdybych místo toho pracoval na něčem, co generuje přímý zisk, tak mi (s trochou nadsázky) vyšlo, že jsem si mohl pořídit dům nebo dvě Tesly S. Nicméně jen na našich projektech už DotVVM ušetřilo velkou část toho, co nás stálo, takže i kdyby ho nikdo kromě nás nechtěl, časem se nám ta investice vrátí. Nehledě na to, že jsme se naučili obrovské kvantum nových věcí, získali spoustu nových zkušeností, a že nás to (aspoň většinu času) bavilo a posunulo dál.
Nicméně, během těch 14 dní, co se DotVVM dá koupit, jsme již několik licencí prodali (dokonce většinu mimo ČR), a ohlasy jsou na to velmi pozitivní, přišlo mi už několik mailů od různých lidí, že to je přesně to, co hledali.
Na tomto místě bych chtěl poděkovat všem, kteří se na DotVVM podíleli, ať už přímo tím, že pro něj něco vyvíjeli, anebo i tím, že pracovali na jiných projektech a umožnili tím, aby se na vývoj mohli soustředit ostatní.
A samozřejmě i těm mimo naši firmu, kteří DotVVM již začali používat a posílali nám celou dobu cenný feedback. Díky. Bez vás by se to nepovedlo.