Gorrion Unplugged #2: cztery spojrzenia na front-end

Artykuł dostępny również w językach:
Liczba odsłon: 342

Jeżeli in­te­re­su­jesz się pro­gra­mo­wa­niem war­stwy front-end i cie­ka­wi Cię, któ­re osno­wy i na­rzę­dzia pro­gra­mi­stycz­ne są obec­nie „na to­pie”, miej­scem Two­je­go po­by­tu we wto­rek 26 czerw­ca o 18:00 po­win­na by­ła być gli­wic­ka sie­dzi­ba fir­my Gorrion. Zorganizo­wa­ne przez nią spot­ka­nie by­ło po­świę­co­ne trzem naj­istot­niej­szym mo­ty­wom pro­gra­mo­wa­nia war­stwy użyt­kow­ni­ka apli­kac­ji web: pro­gra­mo­wa­niu re­ak­tyw­ne­mu, os­no­wom pro­gra­mi­stycz­nym oraz te­sto­wa­niu inter­fej­su użyt­kow­ni­ka. Poniżej znaj­dzie­cie re­la­cję z te­go wy­da­rze­nia.

Gorrion Unplugged #2
Źródło: https://pl-pl.facebook.com/GorrionSoftwareHouse/

Można na­rze­kać na to, jak apli­kac­je sie­cio­we znisz­czy­ły spój­ność inter­fej­su użyt­kow­ni­ka, jed­nak trud­no za­prze­czyć, że to one sta­no­wią na ra­zie je­dy­ny sen­sow­ny spo­sób, by do­trzeć z opro­gra­mo­wa­niem do wszyst­kich użyt­kow­ni­ków, nie­za­leż­nie od uży­wa­ne­go przez nich sys­te­mu opera­cyj­ne­go czy plat­for­my mo­bil­nej. Każda apli­kac­ja web jest jed­nak pi­sa­na w in­ny spo­sób, z wy­ko­rzys­ta­niem in­nych osnów pro­gra­mis­tycz­nych oraz in­ne­go spo­so­bu usta­la­nia wy­glą­du ele­men­tów. Każda mu­si też być do­głęb­nie prze­tes­to­wa­na, gdyż nie­za­leż­nie od te­go, jak do­brze zo­sta­ła za­pro­jek­to­wa­na archi­tek­tu­ra roz­wią­za­nia, zmia­ny w jed­nej częś­ci ko­du mo­gą po­ten­cjal­nie unie­ru­cho­mić in­ne mo­du­ły apli­kac­ji, ska­zu­jąc pro­gra­mis­tów na gniew użyt­kow­ni­ków i kie­row­nic­twa.

Prezentac­je w ra­mach Gorrion Unplugged do­ty­ka­ły właś­nie tych za­gad­nień. Pierwszą z nich, za­ty­tu­ło­wa­ną „A million ways to sty­le your React com­po­nents”, Michał Lytek po­świę­cił za­gad­nie­niom usta­la­nia wy­glą­du apli­kac­ji pi­sa­nych z wy­ko­rzys­ta­niem osno­wy React. W pierw­szej częś­ci przed­sta­wił on wcześ­niej sto­so­wa­ne tech­ni­ki, od za­mierzch­łych cza­sów jQuery, przez ko­lej­ne wcie­le­nia bi­blio­te­ki AngularJS, aż po roz­wią­za­nia sto­so­wa­ne w React. Każda ko­lej­na tech­ni­ka zwięk­sza­ła po­ziom ab­strak­cji i ułat­wia­ła uni­ka­nie po­wie­la­nia ko­du.

Najnow­szym roz­wią­za­niem, da­ją­cym naj­więk­sze moż­li­woś­ci, jest bi­blio­te­ka Styled Components, w któ­rej po­łą­czo­no moż­li­woś­ci okre­śla­nia wy­glą­du ele­men­tu za po­mo­cą ję­zy­ków CSS oraz Java­Script. Bibliote­ka po­zwa­la de­fi­nio­wać no­we ele­men­ty React za po­mo­cą wy­ra­żeń Java­Script, a opis sty­lu wy­ko­nu­je się wy­ra­że­nia­mi CSS. Definicje sty­lu mo­gą być jed­nak du­żo bar­dziej skom­pli­ko­wa­ne: moż­na sto­so­wać wy­ra­że­nia wa­run­ko­we, a tak­że wy­wo­ły­wać wy­ra­że­nia lamb­da lub peł­no­praw­ne funk­cje Java­Script. Kolejne de­fi­ni­cje ele­men­tów mo­gą ba­zo­wać na wcześ­niej­szych, dzię­ki cze­mu uzys­ku­je się zna­ko­mi­te po­wtór­nie wy­ko­rzys­ta­nie ko­du. Możliwe jest też sto­so­wa­nie tech­ni­ki mixin (znie­na­wi­dzo­nej przez or­to­dok­sów pro­gra­mo­wa­nia obiek­to­we­go), dzię­ki któ­rej moż­na łą­czyć wy­bra­ne de­fi­ni­cje cech wi­zu­al­nych w kon­glo­me­ra­ty.

W trak­cie prze­pro­wa­dzo­nej na ży­wo de­mon­stra­cji pre­le­gent po­ka­zał, jak łat­wo zwyk­ły przy­cisk umiesz­czo­ny na stro­nie moż­na prze­bu­do­wać tak, aby nie tyl­ko przy­jął po­żą­da­ny wy­gląd, lecz rów­nież miał wie­le wa­rian­tów róż­nią­cych się ko­lo­rem lub spo­so­bem ani­ma­cji. Wyjaśnił też, w ja­ki spo­sób bi­blio­te­ka tłu­ma­czy skom­pli­ko­wa­ne nie­raz de­fi­ni­cje sty­lu na zopty­ma­li­zo­wa­ne de­fi­ni­cje klas CSS wstrzy­ki­wa­ne do tek­stu źród­ło­we­go na eta­pie bu­do­wa­nia ko­du stro­ny.


Druga pre­zen­tac­ja, któ­rą przy­go­to­wał Tomasz, by­ła po­świę­co­na prze­cho­wy­wa­niu sta­nu apli­kac­ji web. Architek­tu­ra ba­zu­ją­ca na sta­nie jest jed­nym ze spo­so­bów roz­wią­za­nia prob­le­mu prze­wi­dy­wal­no­ści dzia­ła­nia pro­gra­mu nie­za­leż­nie od licz­by źró­deł zda­rzeń. Stan apli­kac­ji jest opi­sa­ny jed­nym nie­mu­to­wal­nym obiek­tem. Zawartość te­go obiek­tu de­cy­du­je o wy­glą­dzie i za­cho­wa­niu inter­fej­su użyt­kow­ni­ka. Z kolei ze­wnętrz­ne zda­rze­nia, ta­kie jak dzia­ła­nia użyt­kow­ni­ka i da­ne prze­sy­ła­ne przez ser­wer, po­wo­du­ją po­ja­wia­nie się ak­cji, bę­dą­cych obiek­to­wym opi­sem zda­rzeń i przy­po­mi­na­ją­cych wzo­rzec pro­jek­to­wy po­le­ce­nia. Zmiana sta­nu jest prze­pro­wa­dza­na na pod­sta­wie do­tych­cza­so­we­go sta­nu i in­for­mac­ji o ak­cji przez re­duk­tor, speł­nia­ją­cy za­ło­że­nia czys­tej funk­cji (funk­cji w sen­sie ma­te­ma­tycz­nym, któ­rej wy­nik za­le­ży wy­łącz­nie od ar­gu­men­tów). Ponie­waż stan jest nie­mu­to­wal­ny, każ­da zmia­na po­wo­du­je po­wsta­nie no­we­go obiek­tu sta­nu.

Tego ty­pu dzia­ła­nie zo­sta­ło za­im­ple­men­to­wa­ne mię­dzy in­ny­mi w bi­blio­te­ce Redux, sto­so­wa­nej w po­łą­cze­niu z React. Jednak nie ozna­cza to, że pro­gra­miś­ci pre­fe­ru­ją­cy AngularJS nie mo­gą two­rzyć apli­kac­ji w ten spo­sób. Osnowa ngrx/store sil­nie in­te­gru­je się z AngularJS, dzię­ki cze­mu łat­wo moż­na prze­kształ­cić dzia­ła­nia użyt­kow­ni­ka w obiek­ty ak­cji prze­ka­zy­wa­ne do re­duk­to­ra, a w efek­cie wpły­nąć na wy­gląd i za­war­tość inter­fej­su użyt­kow­ni­ka. Dodatkowo, ze­staw na­rzę­dzi pro­gra­mis­tycz­nych obec­ny w bi­blio­te­ce ułat­wia diag­no­zo­wa­nie dzia­ła­nia pi­sa­nych pro­gra­mów bez­po­śred­nio z po­zio­mu prze­glą­dar­ki WWW.

Koncepcja nie­mu­to­wal­ne­go sta­nu apli­kac­ji jest nie­zmier­nie cie­ka­wa i mo­że zna­czą­co po­pra­wić ja­kość opro­gra­mo­wa­nia, szcze­gól­nie two­rzo­ne­go przez wie­le osób. Ma ona jed­nak dwa sła­be punk­ty. Pierwszy z nich zo­stał wy­mie­nio­ny przez pre­le­gen­ta i jest nim sam re­duk­tor, któ­ry mu­si ob­słu­gi­wać wszyst­kie wa­rian­ty ak­cji. Istnieją jed­nak roz­wią­za­nia po­zwa­la­ją­ce wy­dzie­lić lo­gi­kę wy­ko­nu­ją­cą po­szcze­gól­ne ak­cje i uzys­kać du­żo bar­dziej przej­rzy­sty i łat­wiej­szy w roz­bu­do­wie kod. Nie zo­sta­ło jed­nak nie­ste­ty po­wie­dzia­ne, do ja­kie­go roz­mia­ru sta­nu kon­cep­cja spraw­dza się w prak­ty­ce. Wadą obiek­tów nie­mu­to­wal­nych jest bo­wiem brak moż­li­woś­ci mo­dy­fi­ko­wa­nia du­żych zbio­rów da­nych, a w efek­cie spo­ra nie­efek­tyw­ność wy­ko­rzys­ta­nia pa­mię­ci. Niemutowal­ny stan nie spraw­dził­by się za­tem wed­ług mnie w przy­pad­ku two­rze­nia apli­kac­ji ta­kich jak edy­tor tek­stu lub ar­kusz kal­ku­la­cyj­ny.

Również w przy­pad­ku te­go wy­stą­pie­nia zo­sta­ła zreali­zo­wa­na ses­ja live demo, pod­czas któ­rej pre­le­gent uru­cho­mił pros­tą apli­ka­cję li­sty za­dań do wy­ko­na­nia, w któ­rej przy­ci­ski do­da­nia no­we­go za­da­nia oraz usu­nię­cia jed­ne­go z za­dań zo­sta­ły skon­fi­gu­ro­wa­ne tak, aby ge­ne­ro­wać obiek­ty ak­cji wpły­wa­ją­ce na stan apli­kac­ji za­pa­mię­ty­wa­ny przez ngrx/store.


Trzecie wy­stą­pie­nie po­pro­wa­dził Dominik Guzy. Poświęcił je przed­sta­wie­niu bi­blio­te­ki VueJS i po­rów­na­niu jej z React, obec­nie bar­dzo mod­ną i po­pu­lar­ną. Prezenta­cja by­ła nie­co prze­wrot­na, gdyż pre­le­gent od ra­zu na po­cząt­ku przy­znał się, że nie uży­wa VueJS i nie jest spe­cjal­nie po­zy­tyw­nie na­sta­wio­ny do te­go pro­duk­tu. Mimo to sta­rał się obiek­tyw­nie po­ka­zać moc­ne i sła­be stro­ny bi­blio­te­ki.

VueJS to osno­wa pro­gra­mi­stycz­na cie­szą­ca się bar­dzo du­żym za­in­te­re­so­wa­niem, bar­dziej po­pu­lar­na na­wet od React. Łączy ona naj­cie­kaw­sze ce­chy AngularJSReact, da­jąc moż­li­wość pro­gra­mo­wa­nia re­aktyw­ne­go oraz dwu­stron­ne­go wią­za­nia pól z mo­de­la­mi da­nych. Charakte­ry­zu­je się też wy­so­ką wy­daj­noś­cią, nie­wiel­kim roz­mia­rem, a prze­de wszyst­kim wy­jąt­ko­wo bo­ga­tym eko­sys­te­mem ofi­cjal­nie wspie­ra­nych roz­sze­rzeń.

Jako naj­więk­sze wa­dy VueJS pre­le­gent wy­mie­nił mu­to­wal­ność sta­nu apli­kac­ji oraz opi­sy­wa­nie kom­po­nen­tów apli­kac­ji w po­je­dyn­czych pli­kach łą­czą­cych kod HTML, de­fi­ni­cje sty­lu oraz lo­gi­kę oży­wia­jąc­ą kom­po­nent. To, czy te ce­chy są rzeczy­wiś­cie wa­da­mi za­le­ży oczy­wiś­cie od kwa­li­fi­ka­cji ze­spo­łu pro­gra­mi­stycz­ne­go oraz roz­mia­ru apli­kac­ji. W każ­dym ra­zie kon­kluz­ją wy­stą­pie­nia by­ło, że o ile VueJS ze wzglę­du na świet­ną do­ku­men­tac­ję, spój­ność oraz względ­ną pros­to­tę wy­ko­rzys­ta­nia do­brze na­da­je się do nau­ki pro­gra­mo­wa­nia w Java­Script oraz two­rze­nia nie­wiel­kich apli­kac­ji ko­mer­cyj­nych, du­że pro­gra­my pi­sze się i diag­no­zu­je du­żo spraw­niej za po­mo­cą React.


Ostatnia pre­zen­tac­ja, po­pro­wa­dzo­na przez Łukasza Wrońskiego, zo­sta­ła za­ty­tu­ło­wa­na od­waż­nie „Poznaj Cypress.io i raz na zaw­sze po­rzuć Selenium”. Autor po­świę­cił ją za­gad­nie­niu auto­ma­tycz­ne­go tes­to­wa­nia funkcjo­nal­ne­go apli­kac­ji web. Tradycyj­nie za­da­nie to reali­zu­je się za po­mo­cą opro­gra­mo­wa­nia Selenium. W nie­któ­rych przy­pad­kach, gdy tes­to­wa­na stro­na WWW jest moc­no asyn­chro­nicz­na, pa­kiet ten nie ra­dzi so­bie jed­nak z właś­ci­wym ko­lej­ko­wa­niem ope­rac­ji i mo­że sto­cha­stycz­nie zgła­szać błę­dy w po­praw­nie rea­li­zo­wa­nych tes­tach. Nie jest też łat­we skon­fi­gu­ro­wa­nie te­stów i zin­te­gro­wa­nie ich ze śro­do­wis­ka­mi CI.

Alterna­ty­wą jest Cypress.io. Jest to bi­blio­te­ka do auto­ma­ty­zo­wa­nia te­stów funkcjo­nal­nych, na­pi­sa­na w ca­ło­ści w ję­zy­ku Java­Script. Podstawo­wym jej za­ło­że­niem jest jak naj­dok­ład­niej­sze od­two­rze­nie dzia­łań rea­li­zo­wa­nych przez użyt­kow­ni­ka. W prze­ci­wień­stwie do Selenium, Cypress.io we­ry­fi­ku­je, czy zle­ca­na ak­cja mo­że być w da­nej sytu­acji wy­ko­na­na i nie po­zwo­li za­sy­mu­lo­wać na­ciś­nię­cia przy­ci­sku któ­ry zo­stał prze­sło­nię­ty in­nym ele­men­tem stro­ny lub uczy­nio­ny nie­wi­docz­nym. Bibliote­ka po­zwa­la też sy­mu­lo­wać wszyst­ko, co mo­że zro­bić użyt­kow­nik, włącz­nie z na­cis­ka­niem kla­wi­szy spe­cjal­nych oraz zmien­nym tem­pem wpi­sy­wa­nia tek­stu.

Bibliote­ka ta mo­że być uru­cho­mio­na z usta­wie­nia­mi do­myśl­ny­mi i od ra­zu rea­li­zo­wać te­sty zde­fi­nio­wa­ne przez pro­gra­mis­tę. Testy rów­nież opi­sy­wa­ne są wy­ra­że­nia­mi Java­Script za po­mo­cą przej­rzy­ste­go API zreali­zo­wa­ne­go zgod­nie z ideą fluent in­ter­fa­ce. Pełna in­te­grac­ja ze śro­do­wis­kiem pro­gra­mi­stycz­nym Java­Script ozna­cza, że te­sty ma­ją moż­li­wość wpły­wa­nia na tes­to­wa­ny kod, co po­zwa­la wstrzy­ki­wać imi­ta­cje wy­bra­nych mo­du­łów funkcjo­nal­nych i w efek­cie wy­mu­szać pe­wien stan apli­kac­ji lub po­mi­jać kosz­tow­ną cza­so­wo (lub nie­moż­li­wą w śro­do­wis­ku tes­to­wym) ko­mu­ni­kac­ję z ze­wnętrz­ny­mi usłu­ga­mi AJAX.

Podczas gdy Selenium po­tra­fi cza­sem po­czę­sto­wać pro­gra­mis­tę lub tes­te­ra kryp­tycz­ny­mi ko­mu­ni­ka­ta­mi błę­dów, Cypress.io pre­zen­tu­je pod ko­niec prze­bie­gu te­sto­we­go czy­tel­ny ra­port za­wie­ra­ją­cy li­stę wy­ko­na­nych czyn­no­ści oraz zro­zu­mia­łe in­for­mac­je o nie­speł­nio­nych za­ło­że­niach te­stu. Realizację te­stu moż­na ob­ser­wo­wać na ży­wo, jed­nak w przy­pad­ku pra­cy w śro­do­wis­ku CI moż­na zle­cić re­jest­ro­wa­nie prze­bie­gu za po­mo­cą fil­mów i zrzu­tów za­war­toś­ci ekra­nu.

Cypress.io reali­zu­je te­sty w śro­do­wis­ku zbu­do­wa­nym na ba­zie otwar­te­go ko­du prze­glą­dar­ki Chro­mium. Istnieją jed­nak mo­du­ły roz­sze­rza­ją­ce, za po­mo­cą któ­rych moż­na zreali­zo­wać te­sty w śro­do­wis­ku in­nych prze­glą­da­rek WWW. Pozwala to w auto­ma­tycz­ny spo­sób za­pew­nić zgod­ność two­rzo­ne­go opro­gra­mo­wa­nia z prze­glą­dar­ką WWW uży­wa­ną przez klienta.


Wszystkie wy­stą­pie­nia by­ły bar­dzo do­brze przy­go­to­wa­ne i peł­ne cie­ka­wych in­for­mac­ji. Prelegenci po­tra­fi­li utrzy­mać uwa­gę pub­licz­noś­ci oraz – co rów­nież istot­ne – mieś­ci­li się w za­ło­żo­nych pół­go­dzin­nych ra­mach cza­so­wych. Między wy­stą­pie­nia­mi by­ły krót­kie przer­wy po­zwa­la­ją­ce roz­pro­sto­wać koś­ci i odetch­nąć na ta­ra­sie, a na koń­cu spot­ka­nia na go­ści cze­ka­ła ciep­ła piz­za. Gospodarze nie omiesz­ka­li rów­nież do­wie­dzieć się, jak uczest­ni­cy oce­nia­ją po­szcze­gól­ne za­pro­sze­nia, pro­sząc o wy­peł­nie­nie an­kie­ty inter­ne­to­wej.

Mam na­dzie­ję, że cykl spot­kań Gorrion bę­dzie kon­ty­nuo­wa­ny. Przy okaz­ji po­zdra­wiam też pra­cu­ją­cych w fir­mie moich by­łych stu­den­tów, któ­rych bar­dzo mi­ło by­ło spot­kać (i mam na­dzie­ję, że im mnie rów­nież), a jesz­cze mi­lej by­ło zo­ba­czyć, jak po kil­ku la­tach pra­cy za­wo­do­wej nie tyl­ko sto­su­ją tech­ni­ki i za­le­ce­nia, któ­re sta­ra­łem się im prze­ka­zać w cza­sie za­jęć, ale wręcz prze­ko­nu­ją in­nych o ich za­sad­no­ści.


Spotkania z panem to zawsze świetna sprawa! Dziękuję za przybycie, pozdrowienia i ciepłe słowa w relacji, cieszę się, że wydarzenie się podobało i zapraszam na kolejne! :)
"Wadą obiek­tów nie­mu­to­wal­nych jest bo­wiem brak moż­li­woś­ci mo­dy­fi­ko­wa­nia du­żych zbio­rów da­nych, a w efek­cie spo­ra nie­efek­tyw­ność wy­ko­rzys­ta­nia pa­mię­ci. Niemutowal­ny stan nie spraw­dził­by się za­tem wed­ług mnie w przy­pad­ku two­rze­nia apli­kac­ji ta­kich jak edy­tor tek­stu lub ar­kusz kal­ku­la­cyj­ny."
W istocie, gdyby za każdym razem zmiany stanu aplikacji trzeba było tworzyć od nowa cały obiekt, byłoby to wysoce nieefektywne. Dlatego by tego uniknąć, stosuje się structural sharing wraz z bibliotekami takimi jak Immutable.js.
Żeby się niepotrzebnie nie rozpisywać, wklejam link do artykułu który to zagadnienie opisuje:
https://medium.com/@dtinth/immutable-js-persistent-data-structures-and-structural-sharing-6d163fbd73d2