neděle 26. listopadu 2017

Potřebují firmy mobilní aplikace?

V poslední době se častěji setkávám s tím, že se zvyšuje poptávka po psaní nativních mobilních aplikací. Tato potřeba je často inicializována společnostmi, které potřebují své pole působnosti rozšiřovat na mobilní platformě.

Na tom by asi nebylo nic neobvyklého, kdyby ovšem ona potřeba nebyla často způsobena neznalostí současného stavu a toho, co je a není dnes možné.

Před tím, než se dostaneme k technickému řešení, pojďme se podívat na současný stav. Stav z pohledu obyčejného uživatele...

Když si vzpomenu na dobu před 20 lety, tak si s úsměvem vzpomínam na to, jak jsem každý program, který jsem ve svém počítači měl, zkoumal do morku kostí. Důvod proč tomu tak bylo, byl jednoduchý. Neexistovalo příliš mnoho alternativ. Potřebovali jste správce souborů? Byl zde Norton Commander. Chtěli jste si zahrát střílečku? Pustili jste si Doom.

Ta doba byla jednodušší a složitější zároveň. Složitá byla z toho důvodu, že neexistoval internet (alespoň pro běžné uživatele) a jakékoli informace se často předávaly ústní formou.

Jednodušší byla ve výběru. Je psychologicky dokázáno, že čím víc variant máme, tím je menší pravděpodobnost, že si nakonec vybereme. Důvodem je to, že onen výběr na nás v konečném důsledku působí tak složitě, že onu volbu raději odložíme "na později".

Pokud tuto dobu srovnáme s tou dnešní, tak zjistíme, že uživatelé se chovají úplně jinak, než kdysi. Jsme zahlceni aplikacemi. Jsme zahlceni volbami. Chcete aplikaci na poznámky? Pusťte si Google Play a stáhněte si aplikaci na poznámky. Ale teď kterou, že? Kolik jich dnes máme? Deset? Dvacet? Možná tisíc. Volba se stala tím nejsložitějším, co řešíme. Dnes a denně.

A teď si představte, že do této džungle chcete vstoupit jako firma, která nabízí mobilní verzi vaší webové aplikace. Ať už jste společnost, která nabízí prodej šroubků, oken, či firma, která poskytuje různé služby.

Drtivá většina firem se ihned pustí do mobilního vývoje. Ať už pomocí svých zaměstnanců, nebo pomocí subdodavatele. Výsledkem je často aplikace, která stála milióny a její dopad je žalostný. Z povinnosti si jí stáhli zaměstnanci a pak pár kamarádů kolem.

Problém výběru je spojen i s překážkami, které musíme podstoupit. Abyste použili aplikaci na poznámky, jste nuceni pustit Google Play, aplikaci dohledat a poté nainstalovat. A to už někdy bývá tak složitá varianta, že jí uživatelé nepodstoupí.

Pokud se podíváme na chování uživatelů, tak zjistíme, že každý z nás je schopen ovládat a používat pouze omezený počet aplikací. Ať už se jedná o poznámky či vyhledání MHD spojů. Do toho se míchá další překážka.

Většina firem si totiž myslí, že na to, aby nějak upoutala pozornost, musí být unikátní. V případě loga a základních barev daného "brandu" je vše v pořádku. Ale v případě vizualizace a chování samotné aplikace tomu tak již není.

Pokud se opět vrátíme ke statistikám, tak zjistíme, že uživatelé často vyhledávají takový druh aplikací, které jsou podobné těm předešlým. Je fajn, že společnost pro nás připravila svůj unikátní UI frontend, ale nám se nechce učit jejich způsob ovládání.

Díky všem těm profesionálům, jako jsou UX designéři, máme na konci aplikaci, která je často unikátní. Unikátní ale natolik, že jí nakonec umí ovládat jen tester a programátor. Důvodem není to, že by tito lidé špatně odvedli svou práci, ale to, že po určité době trpí profesní slepotou.

Výsledkem našeho snažení je, že máme webovou aplikaci, mobilní aplikaci a tisíce hodin, které ještě před námi stojí, abychom svou práci dokončili.

A zde bych se zastavil....

Skutečně firmy potřebují nativní mobilní aplikace a unikátní vzhled?

Odpověď je samozřejmě, že NE.

Pokud jste si přečetli předchozí odstavce, mohli jste sami najít základní problémy, které se s tím spojují.

Rozdělme si je do dvou částí:

Nativní aplikace:
  • Nativní aplikace jsou drahé na vývoj
  • Nativní aplikaci je často nutné psát duplicitně (Android, iOS)
  • Nativní aplikace se složitě aktualizuje
  • Nativní aplikace se složitě testuje
  • Nativní aplikaci musí uživatel najít a nainstalovat
Uživatelské rozhraní:
  • Pokud je příliš unikátní, uživatelé mu nerozumí a nebudou se ho chtít učit
  • Musí se dobře adaptovat na daném zařízení (responsivní design)
  • Je náročné ho napsat tak, aby bylo co nejvíce identické na mobilu a webu
S těmito problémy se setkává velká většina firem. Ať už existence mobilní a webové verze slouží ke snížení požadavků na helpdesk, či řeší zvýšení prodejů jednotlivých produktů a nebo se snaží poskytnout novou službu. Vždy řeší, jak nejlépe najít kontakt se zákazníkem a ten si udržet. I když nejsem marketingový specialista, tak jsem specialista v IT s dlouholetou praxí tvorby frontendových aplikací.

A jakožto IT specialista Vám můžu garantovat, že pokud vytvoříte unikátní mobilní aplikaci, tak to budete mít velice těžké, i když budete poskytovat sebelepší produkt. Důvodem bude jen a pouze lenost nás uživatelů, protože se nebudeme chtít učit, jak se Vaše aplikace ovládá. Netoužíme po tom si jí instalovat z Google Play a nechat si zabírat dalších X desítek megabajtů (sakra, už takhle máme málo místa). A už vůbec netoužíme po tom, abychom si jí aktualizovali každý týden.

Jak z toho ven?

Odpovědí je Progressive Web Application a Material Design.

PWA aneb Progressive Web Application

PWA je termín, který před pár lety použil Google. Toto označení je použito pro webové aplikace, které používají modernější webové technologie.

Ve výsledku nejde o nic převratného z pohledu technologie. Jde pouze o to, že Google na Android zařízeních je schopen identifikovat takovouto aplikaci.

Abyste si to představili v praxi, tak je to tak, že v prohlížeči narazíte na webovou stránku, která je identifikována jako PWA. Webový prohlížeč Vám poté nabídne možnost tuto aplikaci přidat na plochu. Poté, co toto potvrdíte, máte možnost onu webovou aplikaci používat tak, že se tváří jako nativní.

Součástí této specifikace je něco, čemu se říká "service workers", který Vám umožňuje, aby Vaše aplikace šla používat i v offline režimu.

A v tom je asi největší rozdíl oproti klasické webové stránce. Onen offline režim je totiž naprosto potřebná vlastnost k tomu, aby takováto aplikace šla reálně používat.

Zeptejte se svým programátorů, zda vědí co je PWA a zda skutečně musíte dnes psát nativní aplikace. Často se totiž objevuje argument typu: potřebujeme geolokaci, potřebujeme notifikace. Všechno a mohem více již PWA aplikace totiž umí.

Otázkou není, zda je již na PWA čas. Otázkou spíše je, kdy touto cestou půjdete vy. Tedy tam, kde to technicky dává smysl.

Material Design

Pokud jsme mluvili o unikatním brandu jako hlavním požadavku marketingových specialistů, tak je dobré se zeptat, co to vlastně znamená. Pokud by totiž, do tohoto brandu, někdo, kromě loga a barev, míchal i věci jako jsou například formulářové prvky, menu, apod, tak vězte, že je to špatně.

Na toto si stačí udělat jeden lehký příklad. Spustťe si na Androidu Google Play. Umíte ho ovládat? Pustťe si na Androidu Gmail. Umíte ho ovládat? Pustťe si ....

Finále totiž je, že dnes máme možnost napsat aplikaci tak, aby použila stejné chování, stejné prvky a tím docílit toho, že naší aplikaci budou uživatelé schopni ovládat, aniž bychom museli provádět složité adaptace a školení.

Google to totiž udělal za nás. Dal nám Material Design a tím pádem i způsob, jak uživatelsky navrhnout naší aplikaci.

Unikátní cesta je cesta do neznáma... A pokud nejste Facebook, tak věřte, že cesta do pekla.

Material Design vychází z jednoduché myšlenky, která říká, že musíme klást větší důraz na dotyková zařízení. Současně s tím ale mít možnost použít toto rozvržení i ve webové aplikaci. Jinými slovy. Díky PWA máte aplikaci pouze jednu. Jednou je použita na webu a jednou v mobilu.

Abyste pochopili, proč je třeba formulářový prvek zbytečné navrhovat, podívejte se na výchozí chování v Material Design. Textové pole má svůj popisek, ve chvíli, kdy kliknete do tohoto pole, se popisek posune nahoru a vy stále vidíte, jaké pole vyplňujete. I když drobnost, tak si uvědomte, že šetřit místo je důležitý aspekt, každé správné mobilní aplikace.

Závěr

I když jsme často nuceni použít nesmyslné požadavky byznysu, někdy je dobré se zpět zeptat svých IT specialistů na to, zda se nevymýšlí kolo. Zda skutečně potřebujeme nativní mobilní aplikace a zda skutečně musíme navrhovat unikátní design, abychom se odlišili od zbytku světa.

Já mám v tomto ohledu jasno. Budu za PWA a Material Design bojovat všude, kde to jen půjde. A to ne z důvodu toho, že by v tom byl jen technický pohled, ale také z důvodu toho, že je to cesta, která může společnostem skutečně pomoci...

čtvrtek 2. listopadu 2017

Jak zvýšit výkon React aplikací?


V době, kdy jsem objevil svět javascript knihoven a frameworků (React či Angular), jsem si říkal: "Sakra, to sice vypadá skvěle, ale musí to být příšerně pomalé, ne?"

Pravdou je, že ano i ne. Vše závisí na tom, jak k dané knihovně přistupujete a jak dobře znáte samotné principy, na kterých je daná knihovna postavena. V případě Reactu je samotný princip až stupidně jednoduchý, který z něj ovšem dělá onu krásu. Tady, stejně jako v životě, platí, že ty nejjednodušší varianty jsou ty nejsprávnější.

Pochopit princip, jak funguje React je vcelku jednoduchý. Je to silně komponentově orientovaná knihovna, která využívá principu one-way binding a immutable stavu. Co to ve výsledku znamená, je to, že na porovnání změny stavu Vám stačí dát mezi dva objekty tři rovnítka (===). Ano, to je vlastně celé. Tedy skoro... :)

Tento článek je určen pro všechny, kteří už prošli první zkouškou a tou je napsání "Hello World" v Reactu. Postupně si rozebereme jednotlivé části, které nám mohou ušetřit problémy s výkonem v React aplikacích.

1. Render metoda musí být rychlá

React se točí kolem jedné jediné věci a tou je render. Render fáze se Vám zavolá vždy, když dojde ke změně stavu. Ať už je to na úrovni props či state. Druhou variantou, kdy dochází k volání render fáze je v době, kdy je samotný předek znovu renderován.

Pokud si tyhle věci spojím, tak se dostanu k tomu, že render metoda se volá častěji, než se na první pohled zdá.

A zde je první poučka: "V render fázi nikdy nevykonávejte náročné operace."

A jak zjistit, kolikrát mi daná komponenta volá render? Na to stačí jednoduchý trik. Prostě a jednoduše si do metody dejte "console.log" a podívejte se sami. Šílené, že? :)

2. Nezapomínat na unikátní klíče u listů

Pokud v Reactu vytváříte tabulku či seznam, tak jste si jiště všimli, že když v dané komponentě, která je v iteraci, nemáte definován atribut key, tak Vám React bude hlásit warning. Ten warning neignorujte. Jde totiž o to, že díky tomu, že dané komponenty jsou ve virtuálním DOMu na stejné úrovni, pomáhá to Reactu s indexací. Výsledek je, že pakliže ony klíče nebudete definovat, nebo nebudou unikátní, tak výkon Vaší aplikace bude klesat.

Příklad s atributem key:
import * as React from 'react';

interface Props {
    readonly users: Array<{ id: string; firstName: string; lastName: string; }>;
}

const UsersTable: React.SFC<Props> = ({users}) => (
    <table>
        {users.map(({id, firstName, lastName}) => (
            <tr key={id}>
                <td>{firstName}</td>
                <td>{lastName}</td>
            </tr>
        ))}
    </table>
);

Tady je vidět, jak správně pracovat s iterovanými prvky v JSX.

3. Snažte se o ploché struktury

Na začátku jsme mluvili o tom, že render metoda se volá vždy, když je renderován rodič. Z toho nám vychází jedno důležité pravidlo a tím je, že bychom se měli snažit více o plochou strukturu. Ve výsledku to znamená, že čím máme hlubší struktury našich komponent, tím se zvyšuje riziko vykonnostních problémů.

Vím, že je to někdy těžké, ale netvořte v React aplikacích vlastní šílené univerzum. Atomizace jednotlivých částí je naprosto v pořádku. Nicméně, atomizace prvků neznamená větší hloubku.

4. Callbacky v render bez bind

Dalším pravidlem je nepoužívat bind(this) v callback funkcích v render.

Pojďme si udělat příklad:
import * as React from 'react';

interface Props {
    readonly onClick: (id: number) => void;
}

class Component extends React.Component<Props> {

    handleOnClick() {
        this.props.onClick(1);
    }

    render() {
        return (
            <button onClick={this.handleOnClick.bind(this)}>Klikni</button>
        );
    }

}

Tento kód trpí jedním neduhem. Tím je samotný bind. Pokud jsme si řekli, metoda render je volána často, tak tento kód nám způsobuje, že je stále dokola vytvářena nová funkce.

Pojďmě se podívat na správný přepis:
import * as React from 'react';

interface Props {
    readonly onClick: (id: number) => void;
}

class Component extends React.Component<Props> {

    handleOnClick = () => {
        this.props.onClick(1);
    };

    render() {
        return (
            <button onClick={this.handleOnClick}>Klikni</button>
        );
    }

}

V podstatě jsme funkci handleOnClick přepsali do arrow funkce, což nám umožňuje to, že samotné this, je this třídy a tím pádem ho nemusíme expresivně definovat přes bind(this).

5. Nevytvářejte zbytečně nové objekty

Pokud jsme se bavili o tom, že React funguje na základě třech rovnítek, které nám říkají, zda se jedná o stejný či jiný objekt, tak ve stejném duchu musíme přemýšlet i my.

Pojďme si udělat jednu ukázku a říci, co je na ní špatně:
import * as React from 'react';
import {Detail, Menu, Page} from './components';

class Container extends React.Component {

    getUser() {
        return {firstName: 'Ales', lastName: 'Dostal'};
    }

    render() {
        return (
            <Page user={this.getUser()}>
                <Menu/>
                <Detail/>
            </Page>
        );
    }

}

Na tomhle kódu je špatně jedna věc a tou je samotný fakt, že s každým voláním render metody se stále dokola vytváří objekt user.

Přepis by vypadal následovně:
import * as React from 'react';
import {Detail, Menu, Page} from './components';

const user = {firstName: 'Ales', lastName: 'Dostal'};

class Container extends React.Component {

    render() {
        return (
            <Page user={user}>
                <Menu/>
                <Detail/>
            </Page>
        );
    }

}

Tomuto způsobu se říká "memorizování", kdy pokud víme a máme objekt jasně definovaný, tak ho nechceme stále vytvářet dokola. Z podobným principem se můžeme setkat i jinde (viz níže).

6. S Reduxem používejte reselect

V případě, že používáte Redux, často se setkáváte s tím, že na jedné straně máte nějak uložená data v Redux store a jinak je potřebujete prezentovat do komponenty. První co se nabízí, že v metodě mapStateToProps budete své props různě přepočítávat. Je velká pravděpodobnost, že tímto způsobem budete s každou změnou v Redux store vytvářet i nové objekty ostatních atributů.

Jelikož by ukázka vydala na samotný článek, odkážu rovnou na knihovnu, kterou doporučuji použít: Reselect.

Tato knihovna vychází z principu memorizování dat, čímž pádem snižuje opakovanou tvorbu objektů v props a snižuje tím i nutnost volat častěji render fázi.

7. Občas použijte shouldComponentUpdate

Jsou situace, kdy se dostanete do fáze, že Vaše render fáze je drahá. To znamená, že již víte, že nelze moc najít způsoby, jak jí ještě více optimalizovat a snižovat náročnost aplikace.

Já jsem se s tímto setkal třeba u grafů Highcharts, které v React aplikacích občas používám.

V té chvíli se nabízí další možnost, jak zlepšit výkon React aplikace a tím je využití metody shouldComponentUpdate. Tato metoda má ve výchozím stavu nastaveno "return true", čímž říká, že render se volá tak, jak jsme si popsali. Pokud danou metodu přepíšete, máte možnost určit, za jakých podmínek se bude render metoda volat.

Pojďme si udělat malý příklad:

import * as React from 'react';
import {Options} from 'highcharts';
import * as ReactHighcharts from 'react-highcharts';

interface Props {
    readonly config: Options;
}

export class Highcharts extends React.Component<Props> {

    shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<{}>, nextContext: any): boolean {
        return (nextProps.config !== this.props.config);
    }

    render() {
        return (
            <ReactHighcharts config={this.props.config}/>
        );
    }
}

Jak si můžete všimnout, tak jsem v dané ukázce použil kontrolu třech rovnítek, kde říkám, že pokud se props skutečně změnilo, spusť render. V opačném případě nikoli.

Pokud píšete React aplikaci, ale stále máte výkonnostní problémy, tento způsob je jeden z nejefektivnějších, jak zařídit, aby Vaše aplikace byla opět svižná.

Bohužel to sebou přináší i jedno riziko. Jak jste si jistě všimli, v nadpisu jsem použil slovo "občas" a to zcela záměrně. Jde totiž o to, že někoho by to mohlo vézt k tomu, že vlastně ve všech komponentách bude přepisovat shouldComponentUpdate. Jenže je tam jedno velké ALE. Tím ale je samotný fakt, že byste s každou změnou props a vůbec modelu museli neustále sofistikovaně upravovat implentaci této metody a věřte, že byste se dostali do fáze, kdy by Vaše aplikace nereagovala, tak jak si představujete. A jediným důvodem by byl lidský faktor.

Tím chci říct, že je naprosto korektní, že se u některých komponent volá render velice často. Pokud jsou dané komponenty optimalizovány a v render metodě nepočítáte model vesmíru, tak to nevadí :)

Další variantou jsou PureComponents, o kterých se můžete dočíst v manuálu.

8. Pomáhejte si dalšími nástroji

První věcí, kterou do svých projektů vždy přidávám je tslint a tslint-react. Jedná se o nástroj, který provádí statickou analýzu kódu, který píšete. Výhodou tslintu je i v tom, že má některá pravidla, která jsou nastavena za učelem upozorňování na možné výkonnostní problémy.

Pokud zůstaneme u ladění výkonu, tak další věcí, kterou občas používám je console.log. Ano, nestydím se za to. Naopak. Občas se chci rychle podívat, jak často se mi některá z metod renderuje a je to naprosto korektní způsob. A nemusíte se bát, tslint Vám vynadá za to, že ve svém kódu máte console.log. Proto ho používám pouze pro ladící účely.

K ladění výkonu je vhodný i Chrome DevTools - Performance. Díky tomu můžete provést sofistikovanou analýzu toho, jak se vaše komponenty chovají a kde vzniká potencionální výkonnostní problém. Více se můžete dozvědet z manuálu.

Závěr

Vypsat všechny známé tipy na zvýšení výkonu React aplikací, by bylo trochu mlácení prázdné slámy. Tento článek berte tak, že je dobré se hlavně zamýšlet nad tím, jak Vaše knihovna funguje a podle toho k ní také přistupovat. Pokud bychom k Reactu přistoupili naprosto nekriticky, tak bychom jednoduše mohli skončit s aplikací, která bude uživatelsky nepoužitelná.

Stále mějte na mysli to, že i když React má virtuál DOM, který nám částečně pomáhá se samotným výkonem, tak nás to úplně neochraňuje od toho, abychom neměli výkonnostní problémy.

Pokud Vás napadá další zajímavý tip na zvýšení výkonu, budu rád, když zanecháte komentář.

úterý 29. srpna 2017

Java vs Javascript na serveru

Dlouho jsem přemýšlel, zda se vůbec pustit do porovnání těchto technologií. Vždy jsem kolem tohoto tématu dost kličkoval, protože je natolik kontroverzní, že si asi mnoho lidí bude myslet, že jsem se zbláznil, nebo že porovnávám jablka a hrušky.

Nicméně, vždy je dobré se na technologie podívat právě tímto způsobem. Zjistit, jaké výhody či nevýhody může mít javascript oproti Jave, je přesně to, co možná mnoho lidí hledá.

Abych hned na začátku uklidnil všechny, kteří očekávají, že budu velebit javascript a tvrdit, že je to ta nejlepší technologie na server aplikace, tak je můžu uklidnit. Není. Když člověk potřebuje připevnit poličku, pomocí vrutů, také na to nepoužije kladivo, ale šroubovák. Na druhou stranu, kladivo je zase skvělý nástroj na hřebík. A přesně tímto způsobem bychom měli přemýšlet i při výběru technologií. Nekoukat jen na to, co se nám líbí, ale i na další aspekty, které nakonec můžou rozhnout o úplně jiné variantě.

Pojďme ji nejdříve v rychlosti říct, co stálo za úspěchem Javy, jakožto primárního jazyka na server aplikace....

Java na serveru

Pokud byste udělali mezikorporátní anketu na to, jaké technologie používají na backend systémy, s jistotou vám můžu říct, že by vyhrála Java. Těch důvodů, proč tomu tak je, je hned několik.

Java je multiplatfomní
Asi bych to shrnul do jedné věty: "Můžeme mít server na linuxu". A to je to, co přesně spoustu firem chce. Naproti tomu, je to přesně ten samý důvod, proč se C# nestal králem. Ač se o to snaží, myslím, že už se to nikdy nepovede. Existuje spoustu firem, které mají stack na .NETu, ale věřte mi, že v celkovém měřítku hrají druhé housle a vždycky hrát budou.

Java má/měla J2EE specifikaci
V době, kdy se java stala populárním jazykem, tak Sun Microsystems udělal jeden dobrý tah. Vytvořil dvě základní specifikace J2SE a J2EE. Ta první se týkala Javy na klientovi a ta druhá na serveru. Ona specifikace nebyla nijak převratná. Naopak, v dnešní době byste na staré EJB koukali jako na jeden velký antipattern. Však i Rod Johnson o tom napsal knihu a tím vlastně vznikl Spring Framework, který kraluje dodnes.
Ale přesto, byla to specifikace. Na tomto základě začaly vznikat aplikační servery a vůbec celý ekosystém kolem javy se stal robustním. Robustním natolik, že pokud někdo dnes řekne, že potřebuje vytvořit větší systém, ihned většině architektům a vývojářům vyskočí java.

Java je staticky typovaný jazyk
Dalším důvodem, proč se Java stala tak populární je to, že je to staticky typovaný jazyk. Zjednodušeně to znamená, že pokud píšete kód, musíte deklarovat typy. Pokud byste toto pravidlo porušili, projekt se vám jednoduše nezkompiluje. Dnešní editory kódu umí dělat kompilaci za běhu a tak programátorovi rovnou říkat, kde má chybu.
Toto se ukázalo jako důležitá vlastnost jazyka. V případě, že upravujete existující projekt, budete za staticky typovaný jazyk rádi.

Java je objektově orientovaný jazyk
Psát o tom, co je OOP je asi zbytečné. Na toto téma existuje milióny článků. Nicméně uvést to jako důvod musím. Bez OOP by nebyla Java a bez Javy by nebyl svět tak zfanatizován pojmem OOP :)
Díky tomuto principu totiž vznikly věci jako je například DI/IoC kontejnery. A tím nejznámějším právě onen Spring.

Java má garbage collector
Garbage collector, nebo chcete-li sběrač odpadků je vlastnost, díky které se v Jave příliš nestaráte o to, jak váš projekt alokuje zdroje. Zjednodušeně se dá říct, že vedle vaší aplikace běží agent, který se snaží o to, aby po vás čistil to, co máte v naalokované paměti. Tím se snižuje riziko, že napíšete aplikaci, která shodí celý server.

O Jave by se dalo napsat spoustu zajímavých věcí. Sám jsem s tím jazykem žil 10 let. V době, kdy jsem Javu objevil a kdy jsem se jí naučil, jsem si myslel, že už nic lepšího nemůže být. Nicméně žijeme v roce 2017 a je dobré asi zmínit ještě jednu věc. Vím, že tím asi naštvu část javistů, ale pravdou je, že java svůj vrchol slávy má nejspíše za sebou. Její stagnace v podobě nových vlastností je jasná ukázka toho, že její budoucnost není tak růžová, jak si možná někdo myslí.

Nyní se konečně pojďme podívat na Javascript....

Javascript na serveru

Javascript na serveru nemá příliš dlouhou historii. Pokud bych měl být objektivní, tak bych nejspíše řekl, že se javascript spíše hledá. Pokud někdo zvolí javascript jako server technologii, měl by si nejdříve zjistit několik věcí, které se nakonec můžou stát zásadním blokujícím problémem.

Node.js

Pokud budeme mluvit o javascriptu na serveru, tak je nutné zmínit samotné běhové prostředí. Zjistil jsem, že existuje spoustu lidí, kteří vlastně vůbec netuší, co je ono Node.js.

Takže ještě jednou: "Node.js je běhové prostředí". Stejně tak, jako je pro Javu běhové prostředí JVM či pro C# .NET.

Abychom z Node.js vytvořili server, necháme náš skript bežet na námi definovaném portu. Nic víc, nic míň.

Single thread

Javascript je single thread. To je asi nejzásadnější věc, se kterou musíme hned od začátku počítat.

V jave je to nejčastěji tak, že se každý request spustí ve vlastním threadu. Výhodou tohoto řešení je, že se neblokují další requesty, které přicházejí v okamžiku zpracování.

Naproti tomu v Node.js všichni klienti sdílejí pouze jeden thread. Abychom to lépe pochopili, pojďme si udělat jednoduchou ukázku:
import * as Express from 'express';

const app = Express();

app.get('/', (request, response) => {
    response.json({success: true});
    const start = Date.now();
    while (true) {
        if ((Date.now() - start) > 5000) {
            break;
        }
    }
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
    console.log(`Application ready on port: ${port}`);
});

V případě, že nyní zavoláte http://localhost:8080/, tak ihned dostanete odpověd v podobě {"success": true}. V případě, že se znovu pokusíte poslat request, bude celý thread zablokovaný 5 vteřin.

Toto je jednoduchý důkaz toho, jak funguje samotné Node.js.

Asi každého hned napadne, že pokud je Node.js single thread, tak v něm napsat použitelnou server aplikaci je nemožné. Opak je pravdou...

Event loop / Async await

Abychom byli schopni použít Node.js v produkci, je třeba dodržet několik pravidel. Tím nejzákladnějším je, že vše musí asynchronní.

Jelikož víme, že javascript je single thread, tak jak vlastně může fungovat taková metoda setTimeout, jak vlastně může fungovat Promise, či obecně všechny callbacky?

Odpovědí je event loop. Pokud se chcete detailněji seznámit s tímto mechanismem, můžete začít klidně zde: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

Pojďme si to zjednodušit. Samotné callbacky fungují tak, že se pustí v podprocesu vedle a dále se vykonává náš kód.

Pojďme si udělat krátkou ukázku:
const runDirect = () => {
    console.log('This is direct');
};
const runLater = (timeout: number) => {
    setTimeout(() => {
        console.log(`This is later with timeout: ${timeout}`);
    }, timeout);
};

runDirect();
runLater(100);
runLater(0);
runDirect();

Výsledkem bude:
This is direct
This is direct
This is later with timeout: 0
This is later with timeout: 100

Toto je ukázka toho, že v javascriptu existuje asynchronní zpracování.

Nyní si pojdmě ukázat, jak nepsat a jak psát kód na serveru:
import * as Express from 'express';
import sync_query from 'sync-query';
import async_query from 'async-query';

const app = Express();

app.get('/bad', (request, response) => {
    const users = sync_query('SELECT * FROM users');
    response.json({users});
});

app.get('/good', (request, response) => {
    async_query('SELECT * FROM users').then((users) => {
        response.json({users});
    });
});

app.get('/better', async (request, response) => {
    const users = await async_query('SELECT * FROM users');
    response.json({users});
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
    console.log(`Application ready on port: ${port}`);
});

V případě první routy bad bychom se dostali do stavu, kdy bychom mohli celé vlákno zastavit a souběžné zpracování by nebylo možné. Tedy ostatní volající by čekali, než by celá metoda byla vykonána. Je to tedy přesně ta ukázka, která říká: "Takto ne.".

Routa good a better je v podstatě ten stejný zápis. Využívá vzoru Promise, který je možné přepsat pomocí async/await. Zde je vidět, že se kód vykonává deklarativně. Tedy jedná se o callback, který se "někdy vykoná".

Pokud bychom toto porovnali s tím, jak bychom zapisovali kód v Jave, tak největším rozdílem je to, že v Node.js píši deklarativně. Zjednodušeně řečeno, celá naše aplikace v Node.js bude plná callbacků. V Jave bych psal vše imperativně. Tedy to, co se má vykonat, se vykoná hned a pak následuje další série příkazů.

Alternativy v Javascriptu

Nyní se pojďme podávat na alternativy, které by javista hledal v Node.js

REST - Spring vs Express

První věcí, která se hned nabízí je psaní REST API.

Zde si dovolím tvrdit, že v případě Node.js jste na tom o trochu lépe, než v případě Javy. Nejde tak ani o to, že byste měli k dispozici více možností, právě naopak. Ale hlavně pro to, že tvorba jednotlivých endpointů je v Expressu o dost snažší. Pokud k tomu připočítám podporu middleware v Expressu, nemůže mu svět Javy konkurovat.

Druhou nespornou výhodou je to, že v javascriptovém světě je pro vás JSON přirozený formát. Ač se to na první pohled možná nezdá, o dost se zvyšuje transparentnost zpracování vstupu a výstupu.

Zde bych ještě rád zmínil jednu věc a tou je samotný fakt, že REST API v Node.js je spíše přežitek. Od doby, kdy světlo světa spatřilo GraphQL, neexistuje jediný rozumný důvod používat REST.

DI kontejner - Spring vs ???

Jedna z nejčastějších otázek v javascriptovém světě na serveru je DI kontejner. Od doby, kdy se Node.js objevilo, vzniklo asi tak tisíc knihoven, které měly převést Spring do světa Node.js.

Můžete hádat, kolik z nich se reálně uchytilo a jsou dnes populární jako Spring. Je to přesně 0.

Myslím, že existují dva hlavní důvody proč tomu tak není.

1. Absence anotací
Až do nedávné doby nebylo možné využít AOP princip. Alespoň ne tak efektivně jako v případě Javy. Proto je většina knihoven, které se o DI kontejner snaží, jaksi krkolomná. V budoucnu je možné, že se tato situace změní. Přeci ECMA má nyní dekorátory (čti anotace) a to může celou tuto situaci vyřešit.

2. Javascript je jiný
Druhým důvodem je to, že javascript samotný DI vlastně ani moc nepotřebuje. Respektivě ho nechce. Node.js vychází z patternu modulů, které do svého kódu importujete. Proto existuje velká část javascript vývojářů, kteří místo DI principu volí funkcionální přístup.
O tom, která z těchto variant je lepší se vedou dlouhé diskuze.
Osobně se spíše přikláním k druhé variantě a to tedy, že DI skutečně nepotřebuji. Když si vezmu v potaz to, co skutečně od serveru očekávám, tak jeho výhody mi moc nepomůžou. Abych použil DI jenom kvůli testům a mockování závislostí, tak od toho zde máme knihovny jako proxyquire.

Pokud bych se měl pokusit o objektivní názor, tak zde je na tom Java lépe. Lépe hlavně pro to, že tyto věci má víceméně vyřešené. V javascriptovém světě je toto přesně ta část, která na svůj Spring ještě čeká. Spring který využije funcionálního paradigma.

Persistence - JPA vs Mongoose

Zde se názory asi nejvíce liší. Na jedné straně je skvělé, že mám v Jave věci jako je JPA, na straně druhé je fakt, že JPA je dobré tak pro středně velký projekt.
Pokud bych měl porovnat JPA a Mongoose z Node.js, tak bych jasně řekl, že Mongoose je na tom lépe. Nejde o funkcionalitu, ale samotný fakt, že s MongoDB komunikuji pomocí JSONu. V té chvíli se mi dost stírá ona hranice mezi kódem na serveru a jednotlivými dotazy do databáze.
Java by byla v persistentní vrstvě skvělá. Ale jen v případě, že by databáze byla objektová a ne relační.

Messaging - JMS vs Cloud lambda functions

Pro lidi ze světa Javy je JMS známá technologie. V podstatě jde o to, že slouží asynchronní k výměně informací mezi systémy. Pokud bychom toto hledali v javascriptu, tak nic použitelného nenaleznete. Nicméně v roce 2017 je třeba se zamyslet, zda neexistují i jiné varianty.

Tím nejlepším, co můžeme dnes využít jsou Cloud lambda funkce. Více viz: Google Cloud dokumentace.

Node.js na produkci

Použít javascript na serveru není žádná partizánská činnost. Existuje velké množství firem, které Node.js na produkci používají. Pokud si někdo myslí, že jde o malé firmy, tak je musím zklamat. Javascript na serveru používají takové firmy jako je Microsoft, IBM, PayPal, Netflix či třeba LinkedIn.

Napsat backend v javascriptu může být dobrá, ale také špatná volba. V současném stavu je to tak, že Node.js je vhodné jako backend pro frontend. Pokud onen backend slouží jen jako rozhraní mezi databází a webovou aplikací, tak neexistuje moc důvodů, proč Node.js nepoužít.

Ve chvíli, kdy backend znamená složitou orchestraci jiných systémů, složité výpočty, apod, tak zde je využití javascriptu dost na hraně. Osobně si myslím, že zde javascript ještě není. Nejde ani tak o to, že by to nebylo možné, ale spíše fakt, že samotný jazyk je na tyto účely nedospelý. I když ECMA specifikace postupně napravují škody, které byly na javascriptu napáchány, tak bude ještě nějaký čas trvat, než bude skutečně použitelný i v robustnějších backend systémech.

Závěr

A co vy? Používáte Node.js na produkci?

neděle 30. července 2017

Google Cloud a Node.js


V minlém článku jsem představoval Next.js. Dneska bych se chtěl zaměřit na to, jak samotné Next.js provozovat v Google Cloudu. Kromě samotného Next.js / Node.js si ukážeme i možnost, jak horizontálně škálovat naší novou aplikaci.

Cloud vs In-House

V případě, že v roce 2017 zvolíte In-House vývoj, musíte k tomu mít sakra velký důvod. Existuje snad pouze jedna výhoda a tou je fakt, že máte data tam, kde je přesně chcete mít. Tedy v případě cloudu jste často limitováni v tom, kde vaše data leží.

Pokud si ovšem umíte obhájit to, že data máte v cloudu (např s podporou tokenizace), tak neexistuje žádný další důvod, používat vlastní servery. Použití vlastních serverů je stejné, jako běžet maraton s batohem plným kamení.

Ve chvíli, kdy mluvíme o cloudu jako je AWS, Azure či Google, tak mluvíme hlavně o ekosystému kolem. Jestli v cloudu využíváte pouze virtualizaci serverů a zbytek si řešíte sami, vězte, že to děláte špatně.

Stačí, když si zodpovíte na tyto otázky:
  1. Jak řešíte deploy aplikací?
  2. Jak řešíte logování?
  3. Jak řešíte monitoring?
  4. Jak řešíte databázi?
  5. Jak řešíte škálování (vertikální i horizontální)?
  6. Jak spravujete load balancing?
  7. Umíte jednoduše část svých requestů přesměrovávat na nové verze?
  8. Jak řešíte bezvýpadkové nasazení?
Pokud vaší odpovědí je všude cloud služba, gratuluji. Pokud ne, tak jaký je důvod, že si to řešíte sami? Není to náhodou neznalostí cloud služeb? Nebo je důvodem to, že používáte cloud od firmy, která poskytuje pouze virtualizaci? Buďte chytří. Tím, že zvolíte jedno z tria AWS, Azure či Google, si můžete dost svojí práci zjednodušit.

Google Cloud

V době, kdy jsem technologicky stavěl startup, tak jsme se shodli na tom, že vše bude v cloudu. Rovnou jsme tím zavrhli, že bychom v budoucnu řešili lokální nasazení, protože by to znamenalo extrémní nároky na infrastrukturu a vývoj.

V té době byla moje znalost cloud služeb dost omezená a žil jsem v tom, že si rozjedeme vlastní virtuální servery a tam si vše budeme spravovat sami.

Proto první volba padla na Compute Engine, což jsou samotné virtuální servery, kde si "naklikáte" vhodnou Linux distribuci a pomocí SSH konzole doinstalujete vše potřebné.

I když tímto způsobem můžete uspět, bude vás stát mnoho úsilí, abyste si vytvořili správnou infrastrukturu a byli schopni spravovat více tenantů, logování, monitoring, škálování, apod.

Díky tomu, že jsem velký odpůrce hesla: "Nesahej na to, co funguje". Tak jsem stále hledal způsob, jak to udělat jinak.

Tou variantou je App Engine....

App Engine

App Engine je platforma, která slouží k tomu, že vám sama bude spravovat vaší aplikaci. K tomuto účelu si sama umí vytvořit Docker kontejnery, které spouští a spravuje.

Abychom správně pochopili, jak App Engine funguje, je třeba si danou platformu rozdělit na několik částí.

App Engine - Services

Služby, dříve nazývány jako Moduly, jsou základní hlavní částí. Službu si můžete libovolně pojmenovat a současně s tím nastavit i routování na vlastní domény.

Aby to bylo lépe pochopitelné, tak si představte, že máte dvě aplikace. Backend a Frontend. Každá z nich bude nahrána do vlastní služby.

Kromě tohoto dělení, můžete zvolit i jiné. My jsme například služby využili tak, že každý tenant běží pod vlastní službou. Tedy Firma A je pod službou firma-a a Firma B je pod službou firma-b. Když k tomu použijete správné routování služeb, tak jednotlivé firmy budou vystupovat pod vlastní doménou třetího řádu. Tedy: firma-a.vasedomena.cz.

App Engine - Versions

Verze je podskupina služby. Představte si, že jste právě nahráli svou novou aplikaci. Vše funguje jak má a vy jste mezitím vytvořili novou verzi. Nová verze byla otestována a dostala nálepku "production ready".

Pokud využívate verze v App Engine, máte nyní několik možností:
  1. Po nasazení vypne původní verzi a nová verze se stane výchozí
  2. Po nasazení bude neaktivní a spustí se až na manuální zásah
  3. Po nasazení přesměruje třeba 10% requestů a zjistí se, zda na produkci nezpůsobuje problém
Toto je vlastnost, kterou na App Engine miluji. Máte velice jednoduše pod správou to, jak se budete chovat k novým verzím vaší aplikace.

App Engine - Instances

Instance jsou poslední částí skládanky. Nyní už víme, že naše aplikace beží pod službou X, má třeba dvě verze 1.1 a 1.2, kde se na verzi 1.2 přesměrovává 30% requestů.

Nyní přišel čas na vertikální a horizontální škálování. Při nasazení aplikace máte možnost si zvolit to, kolik instancí bude existovat. Min/Max. Máte například Node.js backend server, který má vysoký traffic a nároky na výkon. Nastavíte mu 3/20 instancí + lepší procesor + větší pamět. Tedy minimálně tři instance, maximálně 20. V případě frontentu to například bude 2/5 + slabší procesor + méně paměti. Asi každý si dovede představit tu úžasnou variabilitu.

Přesně tímto způsobem spravujeme Node.js. Pokud by se mě někdo zeptal na to, jak spravovat Node.js v produkci, toto je odpověď. Byla by hloupost, kdybychom se snažili ladit Node.js v produkci přes PM2, apod. Nikdy se nedostaneme do takového stavu. Zjednodušeně řečeno: "Lidé z Google vědí lépe, jak Node.js nastavit". Já jim pouze deklarativně řeknu, co od toho očekávám.

App Engine - Další možnosti

App Engine toho nabízí samozřejmě mnohem více. Ať už je to samotný monitoring (služeb, verzí či instancí), tak jsou zde takové věci jako je podpora logování do Stackdriver Logging, Cache, sdílené Sessions, apod.

Třešničkou na dortu mohou být různé kvóty na zdroje, vypínaní v čase, apod.

Node.js v Google Cloudu

Nyní se pojďme již konkrétně podívat na to, jak rozeběhnout Node.js v App Engine. Nejprve popíši celé flow a poté si ukážeme samotné kroky:
  1. Mám webovou aplikaci napsanou v Reactu přes Next.js. 
  2. Celý stack je následující: Typescript, React, Redux, Next.js. 
  3. Zdrojové soubory aplikace jsou uložené v GITu přes Bitbucket.
  4. V Google Cloudu je zrcadlení Bitbucketu do Source Repositories.
  5. Poté se v cloud konzoli provede checkout projektu a samotný deploy
  6. To je vše :)
Samotný deploy aplikace lze samozřejmě automatizovat. Ať už pomocí Bitbucket Pipelines či pomocí Jenkinse. Osobně čekám na to, až bude k dispozici API k AppEngine v google-cloud-node. Dokonce jsem před pár dny položil dotaz na vývojáře, kdy toto bude k dispozcici. Důvod proč bych rád toto API zde měl, je ten, že bych v budoucnu rád dělal deploy přes Cloud Lambda Functions, což vnímám jako optimální variantu.

V minulém článku jsem popisoval jak funguje Next.js s Typescriptem. Takže tento krok rovnou přeskočme. Podívejme se raději na to, jak provést samotný deploy.

Nejprve zmíním, že deploy můžete provést i z lokálního stroje. K tomuto účelu vám stačí nainstalovat si gcloud konzoli a v ní se autorizovat. Poté můžete ovládat cloud ze své konzole pomocí příkazu gcloud.

Aby byl deploy úspěšný, musíte ve svém projektu mít soubor app.yaml, který popisuje základní konfiguraci pro AppEngine. Pokud tento soubor nevytvoříte, tak AppEngine si vytvoří vlastní a aplikaci automaticky nahraje do služby s názvem default.

Ukázka, jak může takový jednoduchý app.yaml vypadat:
env: flex
runtime: nodejs
service: firma-a
Pokud vás zajímá, co vše se dá nastavit, doporučuji se podívat do manuálu.

Další věcí je konfigurace samotného package.json.

Zde je ukázka package.json pro Next.js s Typescriptem:
{
  "name": "@irminsul.cz/test_nextjs",
  "version": "1.0.0",
  "author": "Ales Dostal",
  "scripts": {
    "create-build-id": "node -e \"process.stdout.write(require('./package.json').version)\" > dist/.next/BUILD_ID;",
    "prebuild": "tsc && cp -R static dist/",
    "build": "next build dist",
    "predev": "tsc && cp -R static dist/",
    "dev": "concurrently \"tsc --watch\" \"next dist\"",
    "start": "npm run build && npm run create-build-id && next start dist -p 8080",
    "tslint": "tslint -c tslint.json -p tsconfig.json",
    "deploy": "gcloud app deploy --project apitree-test --version 1-0-0"
  },
  "dependencies": {
    "@types/node": "^8.0.8",
    "@types/react": "^15.0.35",
    "concurrently": "^3.5.0",
    "next": "^2.4.7",
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "tslint": "^5.5.0",
    "tslint-react": "^3.0.0",
    "typescript": "^2.4.1"
  },
  "engines": {
    "node": ">=8.0.0"
  }
}
Je zde několik důležitých věcí, na které nesmíte nezapomenout.

V package.json se definuje verze node.js, na které naše instance poběží. V tomto případě můžete vidět, že jsme zvolili verzi Node.JS 8 nebo vyšší.

Dále je důležité mít ve scripts správně pojmenované commandy. Tím hlavním je "start". AppEngine se totiž bude snažit přesně tento command spustit. S tím souvisí i nutnost samotného portu. Pokud necháme výchozí nastavení, bude AppEngine čekat, že naše aplikace běží na portu 8080.

Pro to, aby v AppEngine správně běžel Next.js, je nutné zde provést jeden drobný hack. Tím hackem je nastavení BUILD_ID. Důvod proč, je ten, že pokud máte více instancí než jednu, tak by vaše aplikace mohla náhodně končit chybou. Více se dozvíte z následujícího issue.

V package.json můžete najít i samotný command pro deploy. Když se na něj podíváte blíže, tak si můžete všimnout, že definuje v jakém projektu bude nasazen a v jaké verzi. Projektem se zde míní hlavní projekt v Google Cloudu.

Nyní už nezbývá než spustit samotný deploy:
npm run deploy

Pokud jste vše nastavili správně, tak gcloud konzole provede následující:
  1. Stáhne si k sobě zdrojové soubory
  2. Vytvoří Docker kontejner s Node.js 8 a vyšší
  3. Nasadí do AppEngine
  4. Spustí na službě "firma-a"
  5. Pod verzí 1-0-0
  6. Spustí npm install
  7. Spustí npm start
  8. V tomto výchozím nastavení použije min 2 instance pro Node.JS

Závěr

Popsat, co všechno Google Cloud umí a to zejména App Engine by bylo příliš vyčerpávající. Tento popis berte jako jeden z návodů, jak rozeběhnout svojí aplikaci na platformě, která vás dostatečně odstíní od nutnosti ručně spravovat Node.js server ve vlastním virtuálním serveru.
Dále je nutné zmínit i to, že Google na svém Cloudu stále pracuje. Proto jsou některé jejich služby v Beta verzích, čímž znemožňují vše využít na 100%. Nicméně tím, že vývoj na této platformě jde rychle dopředu, tak bych se příliš neobával toho, že například tento způsob provozování Node.JS aplikací by byl nepoužitelný. Právě naopak.

A co vy? Už jste přešli na služby v cloudu?

pondělí 24. července 2017

Jak si v IT vydělat hodně peněz?

Na začátek by bylo dobré, abych objasnil samotný titulek, který může na někoho působit jako červený hadr. Článek nebude o obecných pravidlech, ale bude vyprávět můj vlastní příběh, na kterém vám zkusím ukázat, jak se dá docílit úspěchu, či alespoň správně nastartovat svojí vlastní kariéru v IT.

I když se z názvu článku dá dedukovat, že se vše bude točit kolem peněz, není tomu tak. Alespoň ze dvou třetin určitě ne. Ale to už předbíhám, pojďme to raději vzít hezky popořadě...

Kdybychom měli mluvit o roce 2017 jako o přelomové době, nejspíše to nebude pravda. I když pro někoho to může být rok plný úspěchů a štěstí v podobě narození zdravých dětí, svatby či první velké lásky, tak z pohledu lidstva se jedná o rok, který jen kopíruje předešlé a v oblasti technologií nás posouvá stejným tempem jako rok předtím.

Jsem naprosto přesvědčen o tom, že i když se současná doba tak nenazývá, tak prožíváme dobu, která jednou bude označena za revoluční, a to zejména díky vynálezu internetu, který je stále ještě v plenkách. Naše generace prožívá změny, které jsou tak velké, že se s nimi často neumíme ani pořádně sžít. Už samotný vznik mobilních telefonů či sociálních sítí nás naprosto změnil. I když se často mluví o tom, že to má negativní vliv na lidstvo, nemyslím si, že by to bylo tak tragické. S těmito vynálezy, byť v pozměněné formě, se budeme muset pouze naučit žít a vědět, jak je využít ke svému prospěchu.

V digitálním věku vznikl jeden fenomén a tím, jsou všeobecně ajťáci nebo chcete-li konkrétněji programátoři, kteří tvoří něco, co je často nehmotné a těžko uchopitelné. Lidé jim často nerozumí a jejich práci považují za něco nadpozemského, co je mimo běžné chápání. Ať to zní sebepodivněji, tak tento pohled je naprosto běžný. Na základě těchto představ si často lidé ajťáka představí jako podivína s patnácti dioptriemi, mastným vlasem a absencí holky :)

Kromě tohoto zesměšňování, kterému se i já rád sám zasměji, se ještě o ajťácích ví, že berou "slušný prachy". Nejednou můžete někde zaslechnout něco jako: "Kamarád mého kamarádá má kamaráda a ten se zná s programátorem, co bere sto litrů měsíčně někde v bance." Naši rodiče říkávali: "Až vyrosteš budeš doktorem či právníkem, ty se mají dobře.". Dneska byste spíše zaslechli: "Rád bych své děti dal někam na počítače, ajťáci dneska vydělávají spousty peněz.".

Takže jsme se od řezníků, právníků či doktorů, dostali k ajťákům, kteří dnes často mají nejlukrativnější práci ze všech. Abyste se ale do této pozice dostali, nestačí jen chtít, musí tam být i něco víc.

Proto se tedy pojďte se mnou podívat na můj příběh....

Jako malý kluk jsem se často vymykal bežným standardům. Nejenže jsem byl vždy větší jak učitel či učitelka, ale zejména pro to, že mě škola naprosto nebavila a i když to možná zní divně, tak dodnes mám averzi vůči škole.

V době, kdy jsem začal chodit na základní školu, vládnul zde ještě komunismus. Respektive socialismus, který nám jasně určoval co smíme, co nesmíme a čím v budoucnu budeme muset nejspíše být. Pokud jste na základní škole neměli dobré známky, mělo se za to, že jste hlupáci a vaše budoucí povolání bude muset být buď zedník či obráběč kovů. Tedy měli byste jít na učňák a pak do fabriky, kde budete 8 hodin denně stát u stroje.

Jelikož jsem na základní škole příliš nevynikal, měla tahle budoucnost čekat i mě. Však jsem byl dítě, které mělo v první třídě v pololetí známku 3, což znamenalo, že bych se spíše hodil do zvláštní školy. Dokonce o to byl i pokus, abych tam skončil. Naštěstí psycholožka, která měla určit mou budoucnost, řekla, že jsem nadprůměrně inteligentní, akorát hrozně líný. Ta známka tedy byla více způsobena tím, že mě soudružka učitelka neměla moc v oblibě.

Ta lenost se se mnou táhla i dál. V osmé třídě jsem měl čtyřky snad ze všech předmětů, takže bych měl skončit spíše jako pomocník šikovnému zedníkovi. Díky mým rodičům se ovšem nic takového nestalo. Takže, ač jsem se hlásil na střední školu elektrotechnickou, skončil jsem na soukromé chemické, kde moje známky přiliš neřešili.

V té době jsem se začal zajímat o to, jak třeba funguje televize. Nejlepší způsob byl, že jsem jí rozebral. Skvělé, avšak problém byl, že jsem nevěděl, jak ji zase složit. Podobných pokusů jsem jako dítě udělal spousty. Často s negativním výsledkem, protože znalost, která mi chyběla, mi nedovolila můj cíl dokončit.

Střední škola s sebou přinesla jednu věc, která ovlivnila můj další život. Tou věcí byl počítač. V prváku na střední jsem dostal svůj první počítač 286, což i na tu dobu byl už docela historický stroj.

A co s takovým počítačem dělat, když je vám cca 14 let? No přece budete hrát hry. A to jsem přesně dělal. Hraní her byla zábava, kterou jsem do té doby znal jen z maringotek, když k nám přijela pouť a vy jste si za korunu či dvě mohli zahrát svou oblíbenou hru.

Nicméně kromě hraní her mě zajímalo i to, jak to vlastně funguje. Takže jsem opět rozebral počítač a podíval se na něj blíže. Tenkrát se mi podařilo ho sice složit, ale to mi nestačilo. Zjistil jsem, že existuje jakýsi BIOS a v tom se prý dá něco nastavit a třeba ho i zrychlit. Tak jsem nelenil a jal se provést novou konfiguraci. Výsledek? Počítač nefungoval. Musel jsem do nejbližšího krámku s výpočetní technikou, kde mi jeden starší pán pomohl a věnoval mi celý den, aby můj stroj zase uvedl do chodu. A cena? Nic. Jsem rád, že se o to zajímáš, jen v tom pokračuj. Tohle byste dneska už asi nezažili.

Jak jsem získával znalosti, začal jsem i více rozumět tomu, co dělám. Takže jsem se naučil nastavovat lépe konvenční pamět, aby mi fungovala nová hra, či jsem si psal jednoduché skripty v basicu, které sloužily pro různé drobné účely.

Ač se to zdá jako malichernost, přesně tohle byla ta doba, kdy jsem v sobě objevil svou vlastnost, o které jsem do té doby neměl ponětí. Tou vlastností bylo to, že mě hrozně bavilo věci zkoumat a učit se je. Splněný cíl byl jen třešnička na dortu. Byl to skvělý pocit, že fungovalo to, co jsem si přál, aby fungovalo. Nicméně tím cílem byla víc ona cesta.

A to je přesně první část k úspěchu. Pokud chcete dosáhnout úspěchu, musí vás v první řadě bavit samotná cesta. Nakonec zjistíte, že ač máte svůj cíl, tak ve skutečnosti je tím cílem ona cesta.

V IT a vůbec v jakékoli oblasti nemůže člověk uspět, pokud ho nebaví samotná cesta. To poznání je onou drogou. To zkoumání je to, co vás motivuje.

Pokud tohle v sobě nemáte, bude pro vás cokoli dalšího mnohem těžší. Každý máme své okruhy zájmů a pokud to není IT, tak v IT prostě a jednoduše nedělejte. Nestojí to za to. Věřte, že peníze se dají vydělat i jinde. Ale v první řadě hledejte to, co vás skutečně baví.

Střední školou jsem tak nějak proplul a zázrakem dokončil i maturitu. I když známky opět kopírovaly můj běžný standard, tedy žádný zázrak.

Poté jsem chtěl splnit sen rodičů. Půjdu na vysokou školu a budu mít titul.

Bohužel jsem se sice na vysokou školu dostal, ale hned od začátku jsem věděl, že tam nechci být. Nebaví mě to. Počítače máme jednou týdně a ještě tam píšeme v Pascalu diferenciální rovnice, což mně nepřipadalo nijak zajímavé.

Takže jsem opět jako student selhal a odešel. Abych alespoň částečně splnil sen rodičů, šel jsem na vyšší odbornou školu. Pravdou je, že to byla další ztráta mého času, a proto jsem se víc věnoval zábavě v podobě hospody či hraní her. Sice jsem už studoval školu zaměřenou na počítače, ale měli jsme i předměty jako byla ekonomie či právo. Sakra, jak mě to nebavilo.

Jediné, na co jsem se těšil byly počítače, protože v učebnách byly výkonnější stroje a daly se tam hrát lepší hry. To, co jsme tam probírali bylo tak nudné, že jsem to stejně neposlouchal. Nicméně jsem neměl problém projít zkouškou. Prostě a jednoduše, měl jsem už dřívějška tolik znalostí, že jsem to často ani poslouchat nemusel.

Na škole jsem strávil 3 roky a ani jí nedokončil. Nejdříve jsem propadnul a poté se nechal vyhodit, protože už jsem věděl co chci dělat.

V té době jsem si od kamaráda půjčil knížku o PHP. Měl jsem totiž plán, že si napíšu vlastní knihu návštěv. Samozřejmě už jsem měl své webové stránky, jenže byly statické a to mi přišlo málo.

Ta knížka mě chytla a to tolik, že jsem si jí bral i do školy a tajně jí četl pod lavicí, místo abych věnoval pozornost výkladu.

Tak jsem byl vyhozen. Neudělal jsem zkoušku z práva, což byl okrajový předmět, který jsme tam tenkrát měli.

Ač to zní divně, bylo to to nejlepší, co se mi mohlo stát. Vyhazov ze školy.

Jelikož jsem nemohl zůstat bez práce a zedníka či chemika se mi dělat nechtělo, tak jsem se rozhodl pro dráhu programátora. Našel jsem v Praze firmu, která mě zaměstnala a to i s tím, že jsem byl pořádné kopyto, co nic neumělo a pěkně se v tom plácalo.

Můj plat tenkrát činil 12 tisíc korun hrubého. Pro mě to bylo spoustu peněz za něco, co mě navíc strašně baví. Myslel jsem, že jsem dosáhnul svého cíle a teď už nic víc nechci. Ale to jsem se mýlil...

Dnešní doba je taková, že lidé v sobě často nemají pokoru a to zejména v IT. Já bych tenkrát pracoval i zadarmo, protože jsem to prostě chtěl dělat. A to je přesně ono. Opět se vrací moje vlastnost, že ono poznání je mým cílem a to je to, co vás nakonec může vést dál. Proto pokud v IT začínáte, neřešte kolik za to dostanete, dělejte to klidně zadarmo. Pokud jste dobří a chytří, nakonec sami přijdete na to, kde je vaše cena. Ale vše má svůj čas.

Moje nadšení z práce začalo pomalu uvadat. Důvodem nebyl jen fakt, že jsem si uvědomil, že i přes moje znalosti nejsem schopen dostat víc peněz, ale také to, že dělám pořád to samé. Tenkrát jsme tvořili různé jednoduché e-shopy a cms systémy. Samozřejmě jsme na to měli připravené různé šablony, a proto se z kreativní práce začala stávat rutina.

Nakonec jsem odešel, protože mi to přestalo stačit.

Zde je další část pro cestu k úspěchu. Nestůjte na místě. Pokud dosáhnete svého cíle, musíte jít dál. A to i za cenu, že vstoupíte do nekonformní zóny.

Abyste snáze pochopili, co je nekonformní zóna, podívejme se na její opak.

Jedná se o stav, kdy si vytvoříme takové prostředí, kdy nás nic nenutí k tomu, abychom se posouvali dál. Často se to stává lidem, kteří zůstanou v jedné práci déle, než je zdrávo. Vytvoří si své pohodlí, svou práci mají v malíku, a tak velkou část své pracovní doby věnují blbostem. Jinými slovy, začnete degenerovat a tím si zavřete cestu k úspěchu.

Poté, co jsem opustil svou práci jsem si během jednoho dne našel novou. Nebylo by to tak, že bych byl tak strašně dobrej, že by se o mě všude prali, ale to, že jsem ten večer potkal kamaráda, který mi řekl: "Hele, tady zrovna hledají ajťáka, tak se zeptej. Dělá tam můj kámoš."

Tak slovo dalo slovo a za pár dní jsem měl novou práci. Nastoupil jsem jako ajťák do velké firmy, kde hlavním byznysem byla slévárenská a strojírenská výroba.

Mým úkolem bylo dodávání hardwaru zaměstnacům, klasické myši, klávesnice, apod. Druhou činností měl být rozvoj interního informačního systému, kterým se nahrazují nedostatky v primárních ERP systémech.

To bych ovšem nebyl já, abych se nesnažil si cestu usnadnit a věnovat se tomu, co mě skutečně bavilo. Takže došlo k tomu, že jsem se přestal starat o to, zda mají všichni své myšky, klávesnice a psal jen ten informační systém.

V té době jsem se již učil nový jazyk a tím byla Java. Věděl jsem, že pokud chci dělat něco většího a zajímavějšího, musím hledat i jiné prostředky, protože v PHP jsem tu cestu neviděl.

Byla to láska na první pohled. Java byla staticky typová a měla i různá řešení na serveru pod názvem J2EE.

Takže opět moje touha po poznání mi pomohla, abych překročil to, kde jsem začal. Z PHP programátora jsem se pomalu stával javistou a tento svět mě uchvátil.

První co jsem udělal bylo, že jsem si na místní tiskárně vytiskl celou dokumentaci k J2EE, což bylo asi tisíc stran a doma se po večerech učil. Bylo to něco nového a opět mě to posouvalo dál, alespoň jsem měl ten pocit.

Takže zde je další ukázka toho, abyste uspěli. Musíte stále vystupovat do nekonformní zóny. Nestačí to, co umíte. Musíte se stále učit. IT svět není o tom, že nastoupíte do firmy, kde vám dají sto tisíc a vy tam jen sedíte a děláte to, co znáte.

Nějakou dobu vám to vydrží, ale věřte, že vám to nakonec zlomí vaz. Je dobré mít na paměti, že v IT světě je to tak, že 50% vašich znalostí vám za 10 let bude úplně k ničemu. Tedy pokud nechcete sedět v jednom korporátu do té doby, než natolik zdegenerujete, že vás nakonec budou muset sami vyhodit.

Pokračování příště....

neděle 16. července 2017

Funkcionální paradigma: React a Redux

V poslední době se stalo funkcionální programování tématem, o kterém se hodně mluví. Z akademické sféry přešlo do praxe a jak se ukazuje, tak je to způsob, který je v určitých oblastech zajímavou alternativou, nahrazující imperativní přístup.

Dnešní článek bude zaměřen na to, co to vlastně je ten funkcionální přístup. I když na toto téma existuje spousty článků, tak často je vše popisováno příliš abstraktně, což zapříčinilo, že ne každý chápe, o co vlastně jde.

Abych byl schopen demonstrovat tuto problematiku, zvolil jsem si k tomu dvě knihovny, které jsou navrženy podle funkcionálního paradigmatu (alespoň z části).

Funkcionální programování

Přesná definice říká, že se jedná o deklarativní programovací paradigma, které chápe výpočet jako vyhodnocení matematických funkcí.

Samotný program si poté můžete představit tak, že je složen z funkcí, které volají další a další funkce a tím se postupně zjednodušují. Pokud bychom hledali jazyk, který je jednou z vlajkových lodí tohoto přístupu, nejspíše bychom skončili u LISPu či Haskellu.

Druhou důležitou vlastností je to, že funkce nevytváří vedlejší efekt. Ve výsledku to znamená, že na stejný vstup vždy dostávám stejný výstup a nemodifikuje žádný stav. Toto je jedna z důležitých vlastností, kterou se dá odlišit funkcionální a objektový přístup.

Lambda funkce

Abychom byli schopni deklarativního programování, budeme k tomu potřebovat jednu zásadní věc a tím jsou lambda funkce.

Při mém prvním studiu toho, co to vlastně lamba funkce jsou, jsem skončil s plnou hlavou různých teoretických a abstraktních pojmů a stále jsem nechápal, co to vlastně znamená.

Postupně jsem si vytvořil jednoduchou pomůcku, která mi osvětlila tuto problematiku. Tou pomůckou je, že funkci mohu přiřadit do proměnné a tím se proměnná stává funkcí.

Zkusím uvést příklad:

const hello = function(param) {
    return `Hello ${param}`;
};
console.log(hello('World'));

Na tomhle příkladě je vidět, že jsme vytvořili proměnnou s názvem "hello",  která je funkcí.

Příklad je vcelku jednoduchý, tak si ho pojďme trochu rozšířit:

const hello = function(param) {
    return `Hello ${param}`;
};
const helloFromLanguage = function(param) {
    return param('from Javascript');
};
console.log(helloFromLanguage(hello));

Nyní si můžeme všimnout, že jsme vytvořili druhou funkci s názvem "helloFromLanguage", která jako parametr přijímá funkci, kterou sám zavolá.

Nyní si ještě tento příklad přepišme pomocí arrow functions z ES6:

const hello = (param) => `Hello ${param}`;
const helloFromLanguage = (param) => param('from Javascript');
console.log(helloFromLanguage(hello));

To je vše. Lambda funkce a deklarativní programování je vcelku jednoduchá záležitost. Na rozdíl od imperativního přístupu se dá říct, že stále dokola vytváříme callbacky, které se reálně vykonají jinde, než na místě, kde jsme je definovali.

Javascript a funkcionální programování

Pokud bychom o javascriptu mluvili jako o funkcionálním jazyce, tak bychom to museli dát do uvozovek. Přesnější definicí je, že Javascript je hybridní jazyk, ve kterém můžete programovat jak objektově, tak funkcionálně.

I když se často porovnává, zda je lepší objektový či funkcionální přístup, tak si s tím nemusíme lámat hlavu. Osobně si myslím, že se tyto dva přístupy mohou kombinovat a tím těžit z obou paradigmat.

React a funkcionální přístup

Psát o tom, že je React skvělá knihovna pro psaní frontendu, je asi zbytečné. Všichni, co to jednou zkusí a pochopí jeho fungování, tak už nechtějí jinak. Je to stejné, jako když si zvyknete na MacBook, ... ale o tom až jindy :)

V Reactu naleznete několik míst, které "přiznávají" funkcionální přístup.

Pojďmě si několik těchto míst ukázat....

Stateless komponenty

Stateless komponenty jsou funkcí a ničím jiným. Díky tomu nemají žádný interní stav a pokud danou komponentu budeme volat se stále stejnými parametry, budete vždy dostávat stejný výstup.

Pojďme si ukázat jednoduchou komponentu:

interface Props {
    title: string;
}
export const InboxDetailBlock: React.SFC<Props> = ({title, children}) => (
    <fieldset>
        <legend><FormattedMessage id={title}/></legend>
        {children}
    </fieldset>
);

Komponenta přijímá jako vstup props s "title" a "children". Sama nic nemodifikuje, nemá interní stav a pokud jí předáme stejný vstup, vždy bude stejný výstup.

React props

Druhým místem, který lze zmínit jsou samotné props. Props jsou uvnitř komponenty v immutable stavu a tím pádem žádná komponenta nemůže způsobit vedlejší efekt v podobě mutace vstupu. K tomuto účelu slouží callbacky, kterými oznamujeme, že se v komponentě "něco stalo".

Rozšíříme náš příklad o ukázku s callbackem:

interface Props {
    title: string;
    onClick: () => void;
}
export const InboxDetailBlock: React.SFC<Props> = ({title, children, onClick}) => (
    <fieldset onClick={onClick}>
        <legend><FormattedMessage id={title}/></legend>
        {children}
    </fieldset>
);

interface PropsDetail {
}
export const Detail: React.SFC<Props> = () => (
    <InboxDetailBlock title="My block" onClick={() => console.log('Clicked!')}>
        <p>Hello world!</p>
    </InboxDetailBlock>
);

Zde můžete vidět, že komponenta "InboxDetailBlock" má událost na kliknutí na fieldset. Tato událost je směrem k rodiči oznámena pomocí callbacku. Tím se eliminuje nutnost mutace jakéhokoli stavu, který by tuto událost vykonal. Tomuto přístupu se říká "one way binding", kde se událost oznamuje pomocí callbacku a nikoli mutací.

Redux jako globální stav

Pokud jsme se bavili o tom, že metody nemají vedlejší efekt, který by mutoval stav, tak přesně tímto způsobem funguje i Redux. Redux, jakožto implementace Fluxu, vychází z jednoduché myšlenky, která říká: "Máme pouze jeden zdroj pravdy (globální stav) a pokud ho chceme měnit, tak musíme vytvořit jeho kopii, nikoli ho mutovat."
Ve funkcionálním paradigmatu bychom totiž globální stav neměli nikdy mutovat, ale pouze vytvářet jeho nové kopie. Tedy změna stavu je tvorba nového stavu.
V Reduxu k tomuto účelu slouží takzvané reducery, což jsou jednoduché funkce, které přijímají aktuální stav a payload akce. Návratovou hodnotou je poté nový stav.
Jednotlivé React komponenty, které jsou na Redux state navěšeny, poté automaticky reagují na změnu stavu.
Díky tomuto přístupu máte v čase vždy pouze jeden stav. S nadsázkou se dá říci, že pro debugování vám často stačí sledovat redux state a díky tomu víte v jakém stavu je celá vaše aplikace.
Pokud svou aplikaci programujete podle těchto pravidel, tak se vám nemůže stát, že by React či Redux vytvářel vedlejší efekty a čímž vám dost sjednodušuje život.

Závěr

Ve funkcionálním přístupu naleznete spoustu zajímavých témat, viz třeba monády. Cílem tohoto článku nebylo vysvětlit celou problematiku, ale pouze nastínit, jak to vlastně s tímto paradigmatem je.
Funkcionální a deklarativní přístup není spásou pro vše. Nicméně zde je krásně vidět, že existují oblasti vývoje, kde se tento přístup může hodit a ba co víc, může být i hodně prospěšný.
Existuje ještě jedna hezká ukázka a tou je implementace GraphQL, kde pomocí deklarativního zápisu, přes callback "resolve", je velice snadné, aby za GraphQL API byl jakýkoli zdroj, který by byl velice jednoduše měnitelný. Každopádně o GraphQL se ještě něco dozvíte v následujících článcích...

čtvrtek 13. července 2017

Next.js, SSR a Typescript

Existuje jeden hlavní důvod, proč většina lidí s javascriptem skončí dříve, než vůbec začne. Tím důvodem je: "Kde mám sakra začít?".

Gulp, Grunt, Webpack, NPM, Yarn, ES5, ES6, ES2015, Babel, Typescript, Flow, React, Angular, Node.js, Next.js, Redux, Express, Koa, Hapi, .... uff. Nemá cenu si nic nalhávat, svět kolem javascriptu je rozsáhlý a plný slepých uliček. Viz Angular.

V dnešním článku bych se chtěl podívat na knihovnu Next.js, která je úzce spjata s Reactem. A je právě určena k tomu, aby vás odstínila od velkého množství konfigurace, kterou byste sami museli jinak udělat.

Co je Next.js?

Jednou větou: "Next.js je knihovna pro React, která za vás řeší server side rendering a konfiguraci." Server side rendering nebo-li SSR je věc, kterou byste měli sami chtít. Pojďme si nejdříve popsat několik důvodů, proč bychom SSR měli použít.

SEO

Pokud používáte javascriptové knihovny jako je React či Angular a stavíte veřejný web, tak narazíte na to, že Vám ho vyhledávače nebudou chtít správně indexovat. Je velká pravděpodobnost, že zůstanete pro zbytek světa neviditelní. A to přeci nechcete. Zde přichází na řadu SSR, které spočívá v tom, že Vám dopředu vygeneruje "kostru" webové stránky a až poté řeší samotný javascript.
Díky tomu vyhledávač vidí html stránku, ze které si je schopen přečíst informace, které potřebuje pro indexaci.

Velikost stažené aplikace

Ač žijeme v době, která jednou bude popisována jako "začátek digitálního věku", tak je třeba mít na paměti, že i když máme výkonné počítače, tak nás to nespasí v tom, abychom přestali ladit dostupnost a výkon.
Příkladem budiž mobilní zařízení, které předběhly počítače v prohlížení webových stránek. To je skvělá zpráva, nicméně... Nastává totiž problém s rychlostí připojení, které ještě nemáme na takové úrovni jako v případě přímého připojení v domácnostech. Mobilní operátoři nabízí jen velice omezené zdroje a to jak na úrovni rychlosti, tak i v množství stažených dat.
Zde nastupuje druhý argument, proč byste měli SSR chtít. Tím argumentem je fakt, že pokud je Vaše webová aplikace rozsáhlejší, tak klientovi můžete aplikaci posílat po částech. Tedy těch částech, které zrovna vaše aplikace sama potřebuje.

Bílá stránka při prvním načtení

Tento důvod úzce souvisí s předchozím bodem. Jedná se o to, že pokud aplikaci otevíráte poprvé a nepoužíváte SSR, tak vlastně vidíte pouze bílou stránku a to do té doby, než se stáhnou všechny potřebné soubory, což je běžně celá aplikace. V případě pomalejšího připojení je toto velký problém.
Uživatel nechce čekat. Často si bude myslet, že je někde chyba a bude stále dokola zkoušet tlačítko "refresh". A to do té doby, než z vaší stránky odejde úplně.

Proč tedy Next.js a ne vlastní řešení?

Každý, kdo se s Reactem kdy setkal, tak ví, že vytvořit aplikaci, která by se renderovala ze serveru je vcelku jednoduchá záležitost. Problém ovšem nastává ve chvíli, kdy budete tímto směrem nastavovat i další věci. Myslím tím například CSS, Redux či třeba routování. Všechny tyto věci má Next.js již vyřešen a vy pouze využíváte hotové řešení.
Další výhodu, kterou získáte je funkční nastavení webacku či jednoduché spouštěcí skripty. Next.js za vás vše připraví a díky tomu máte stack, který podporuje jak práci v development řežimu, tak i produkční běh.
Next.js toho umí samozřejmě mnohem mnohem více, každopádně k tomuto účelu doporučuji si projít popis na github.com.

Pojďme se nyní podívat na to, jak je na tom Next.js s podporou Typescriptu...

Next.js a Typescript

Pokud chcete v Next.js 2.0 použít Typescript, tak zde narazíte na jeden zásadní problém. Tím problémem je, že podle jejich ukázky na githubu vychází z toho, že zkompilovaný javascript máte ve stejném adresáři jako zdrojové soubory. Faktem je, že tenhle způsob mi nepřijde zrovna vhodný.
V nové připravované verzi máte možnost spustit next.js s parametrem, kde se daný zdroj nachází. K tomuto stačí jednoduchá úprava.

Pojďmě se nejdříve podívat na definici skriptů v package.json:

"scripts": {
    "prebuild": "tsc && cp -R static dist/",
    "build": "next build dist",
    "predev": "tsc && cp -R static dist/",
    "dev": "concurrently \"tsc --watch\" \"next dist\"",
    "start": "next start dist"
  },

Zde můžete vidět, že před spuštěním next.js jen provedet kompilaci pomocí tsc, který podle tsconfig.json kompiluje do adresáře dist.

Konfigurace tsconfig.json vypádá následovně:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "jsx": "react",
    "strict": true,
    "moduleResolution": "node",
    "rootDir": "src",
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "*": [
        "node_modules/*",
        "types/*"
      ]
    }
  },
  "include": [
    "src/**/*"
  ]
}

Podle tohoto nastavení jsou zdrojové soubory v adresáři src a výsledek kompilace ve zmíněném adresáři dist.

Závěr

Osobně vnímám Next.js jako posun k dospělosti. Pokud vývojářům něco chybělo, tak je to dev stack, který by za ně řešil spoustu nudné konfigurace, ale přesto by zůstal dostatečně flexibilní. Tím Next.js přesně je. Chcete doplnit pluginy do webpacku? Žádný problém. Chcete změnit Express na straně Node.js serveru? Také můžete a nebude vás to stát ani příliš úsilí.
Pomocné knihovny, jako třeba Create React App splnily svou historickou povinnost, kdy se čekalo na to, až přijde skupina lidí, kteří tuto věc udělají robusněji.
Nakonec bych si dovolil jedno přirovnání ze světa Javy. To co je Spring Boot pro Spring, to je Next.js pro React. Dělejme opravdu jen to, co musíme.

Když programátor založí a řídí firmu

Jako malý jsem chtěl být popelářem. Ani ne tak proto, že bych měl nějaký zvláštní vztah k odpadkům, ale hrozně se mi líbilo, jak...