Projektowanie i budowanie progresywnej aplikacji internetowej bez frameworka (część 1)
Opublikowany: 2022-03-10Jak właściwie działa aplikacja internetowa? Nie mam na myśli z punktu widzenia użytkownika końcowego. Mam na myśli w sensie technicznym. Jak właściwie działa aplikacja internetowa? Co zaczyna wszystko? Bez żadnego standardowego kodu, jaki jest właściwy sposób ustrukturyzowania aplikacji? W szczególności aplikacja po stronie klienta, w której cała logika działa na urządzeniu użytkownika końcowego. W jaki sposób dane są zarządzane i manipulowane? Jak sprawić, by interfejs reagował na zmiany danych?
Są to pytania, które można łatwo ominąć lub całkowicie zignorować za pomocą ram. Deweloperzy sięgają po coś takiego jak React, Vue, Ember lub Angular, postępuj zgodnie z dokumentacją, aby rozpocząć pracę i odejść. Te problemy są obsługiwane przez zestaw sztuczek frameworka.
To może być dokładnie to, czego chcesz. Prawdopodobnie jest to mądra rzecz, jeśli chcesz zbudować coś na profesjonalnym poziomie. Jednak po oderwaniu magii nigdy nie dowiesz się, jak faktycznie wykonywane są sztuczki.
Nie chcesz wiedzieć, jak się robi sztuczki?
Zrobiłem. Postanowiłem więc spróbować zbudować podstawową aplikację po stronie klienta, sans-framework, aby samemu zrozumieć te problemy.
Ale trochę wyprzedzam siebie; najpierw trochę tła.
Przed rozpoczęciem tej podróży uważałem się za bardzo biegły w HTML i CSS, ale nie w JavaScript. Ponieważ czułem, że udało mi się rozwiązać największe pytania, jakie miałem dotyczące CSS, kolejnym wyzwaniem, jakie sobie postawiłem, było zrozumienie języka programowania.
Faktem było, że z JavaScriptem byłem stosunkowo początkujący. Poza tym, że hakowałem PHP z Wordpressa, nie miałem żadnej ekspozycji ani szkolenia w żadnym innym języku programowania.
Pozwólcie, że zakwalifikuję to stwierdzenie „na poziomie początkującym”. Jasne, mógłbym uzyskać interaktywność działającą na stronie. Przełączaj klasy, twórz węzły DOM, dołączaj je i przenoś itd. Ale jeśli chodzi o organizowanie kodu dla czegokolwiek poza tym, nie miałem pojęcia. Nie byłem pewien, kiedy buduję coś, co zbliża się do aplikacji. Nie miałem pojęcia, jak zdefiniować zestaw danych w JavaScipt, nie mówiąc już o manipulowaniu nim za pomocą funkcji.
Nie miałem pojęcia o „wzorcach projektowych” JavaScriptu — ustalonych podejściach do rozwiązywania często napotykanych problemów z kodem. Z pewnością nie miałem wyczucia, jak podejść do podstawowych decyzji dotyczących projektowania aplikacji.
Czy kiedykolwiek grałeś w „Top Trumps”? Cóż, w wersji web developer moja karta wyglądałaby mniej więcej tak (znaki na 100):
- CSS: 95
- Kopiuj i wklej: 90
- Linia włosów: 4
- HTML: 90
- JavaScript: 13
Oprócz chęci stawiania sobie wyzwań na poziomie technicznym, brakowało mi również kotletów projektowych.
Z prawie wyłącznie kodowaniem projektów innych ludzi przez ostatnią dekadę, moje umiejętności projektowania wizualnego nie miały żadnych prawdziwych wyzwań od późnych lat dziewięćdziesiątych. Zastanawiając się nad tym faktem i moimi nikłymi umiejętnościami w zakresie języka JavaScript, kultywowałem narastające poczucie nieadekwatności zawodowej. Nadszedł czas, aby zająć się moimi niedociągnięciami.
W mojej głowie pojawiło się osobiste wyzwanie: zaprojektować i zbudować aplikację webową JavaScript po stronie klienta.
O nauce
Nigdy nie było więcej wspaniałych zasobów do nauki języków komputerowych. W szczególności JavaScript. Jednak zajęło mi trochę czasu, zanim znalazłem zasoby, które wyjaśniały rzeczy w sposób, który klikał. Dla mnie dużą pomocą były „You Don't Know JS” Kyle’a Simpsona i „Eloquent JavaScript” Marijna Haverbeke.
Jeśli zaczynasz naukę JavaScript, z pewnością będziesz musiał znaleźć własnego guru; ludzie, których metoda wyjaśniania działa dla Ciebie.
Pierwszą kluczową rzeczą, której się nauczyłem, było to, że bezcelowe jest uczenie się od nauczyciela/zasobu, który nie wyjaśnia rzeczy w sposób, który rozumiesz. Niektórzy ludzie patrzą na przykłady funkcji z foo
i bar
i natychmiast szukają znaczenia. Nie jestem jedną z tych osób. Jeśli nie, nie zakładaj, że języki programowania nie są dla Ciebie. Po prostu wypróbuj inny zasób i dalej próbuj zastosować umiejętności, których się uczysz.
Nie jest również pewne, że będziesz cieszyć się każdą chwilą eureki, w której wszystko nagle „kliknie”; jak kodujący ekwiwalent miłości od pierwszego wejrzenia. Bardziej prawdopodobne jest, że potrzeba dużo wytrwałości i znacznego zastosowania zdobytej wiedzy, aby poczuć się pewnie.
Jak tylko poczujesz się choć trochę kompetentny, próba zastosowania swojej wiedzy nauczy cię jeszcze więcej.
Oto kilka zasobów, które okazały się pomocne po drodze:
- Fun Fun Fun Kanał YouTube
- Kyle Simpson Kursy Plural Sight
- JavaScript30.com Wesa Bosa
- Wymowny JavaScript autorstwa Marijna Haverbeke
Racja, to prawie wszystko, co musisz wiedzieć o tym, dlaczego doszedłem do tego momentu. Słoń w pokoju jest, dlaczego nie użyć ramy?
Dlaczego nie zareagować, Ember, Angular, Vue Et Al
Chociaż odpowiedź była wspomniana na początku, myślę, że temat, dlaczego nie został użyty framework, wymaga rozwinięcia.
Istnieje wiele wysokiej jakości, dobrze obsługiwanych frameworków JavaScript. Każdy specjalnie zaprojektowany do tworzenia aplikacji internetowych po stronie klienta. Dokładnie to, co chciałem zbudować. Wybaczam, że zastanawiasz się nad rzeczami oczywistymi: na przykład, err, dlaczego nie użyć jednego?
Oto moje stanowisko w tej sprawie. Kiedy uczysz się używać abstrakcji, to jest to przede wszystkim to, czego się uczysz — abstrakcja. Chciałem nauczyć się rzeczy, a nie abstrakcji rzeczy.
Pamiętam, jak kiedyś uczyłem się trochę jQuery. Podczas gdy urocze API pozwoliło mi uczynić manipulacje DOM łatwiejszymi niż kiedykolwiek, zanim stałem się bez niego bezsilny. Nie mogłem nawet przełączać klas na elemencie bez konieczności jQuery. Zadaj mi podstawową interaktywność na stronie bez jQuery, na której mógłbym się oprzeć, a ja potknąłem się w moim edytorze jak ostrzyżony Samson.
Ostatnio, gdy próbowałem polepszyć swoje rozumienie JavaScriptu, spróbowałem trochę owinąć głowę wokół Vue i Reacta. Ale ostatecznie nigdy nie byłem pewien, gdzie kończy się standardowy JavaScript, a zaczyna React lub Vue. Moim zdaniem te abstrakcje są o wiele bardziej wartościowe, gdy rozumiesz, co dla ciebie robią.
Dlatego jeśli miałem się czegoś nauczyć, chciałem zrozumieć podstawowe części języka. W ten sposób miałem pewne umiejętności, które można było przenieść. Chciałem zachować coś, gdy obecny smak ram miesiąca został odrzucony na kolejną „gorącą nowość”.
Dobra. Teraz dowiadujemy się, dlaczego ta aplikacja została stworzona, a także, czy ci się to podoba, czy nie, jak zostałaby wykonana.
Przejdźmy do tego, czym to miało być.
Pomysł na aplikację
Potrzebowałem pomysłu na aplikację. Nic zbyt ambitnego; Nie miałem złudzeń, że założę biznesowy start-up czy pojawię się na Dragon's Den — moim głównym celem była nauka JavaScriptu i podstaw aplikacji.
Aplikacja musiała być czymś, z czym miałem szansę walczyć technicznie i wykonać na wpół przyzwoitą pracę projektową.
Czas styczny.
Poza pracą organizuję i gram w piłkę halową, kiedy tylko mogę. Jako organizatorowi ciężko jest pamiętać, kto wysłał mi wiadomość z informacją, że gra, a kto nie. Do gry potrzeba zazwyczaj 10 osób, 8 na push. Jest lista około 20 osób, które mogą lub nie mogą grać w każdą grę.
Pomysł na aplikację, na który się zdecydowałem, umożliwiał wybieranie graczy z listy, co pozwalało mi zliczyć, ilu graczy potwierdziło, że może grać.
Gdy myślałem o tym więcej, poczułem, że mogę nieco bardziej poszerzyć zakres, aby można go było wykorzystać do zorganizowania dowolnej prostej czynności zespołowej.
Trzeba przyznać, że Google Earth prawie mi się nie śnił. Miał jednak wszystkie istotne wyzwania: projekt, zarządzanie danymi, interaktywność, przechowywanie danych, organizację kodu.
Jeśli chodzi o projekt, nie zajmowałbym się niczym innym niż wersją, która mogłaby działać i działać dobrze na ekranie telefonu. Wyzwania projektowe ograniczyłbym do rozwiązywania problemów tylko na małych ekranach.
Główna idea z pewnością skłaniała się do zastosowań w stylu „do zrobienia”, których było mnóstwo istniejących przykładów, które można było poszukać w poszukiwaniu inspiracji, a jednocześnie wyróżniały się na tyle, aby zapewnić kilka unikalnych wyzwań związanych z projektowaniem i kodowaniem.
Zamierzone funkcje
Wstępna lista funkcji, które zamierzałem zaprojektować i zakodować, wyglądała tak:
- Pole wprowadzania do dodawania osób do dyżurów;
- Możliwość ustawienia każdej osoby na „wejście” lub „wyjście”;
- Narzędzie, które dzieli ludzi na zespoły, domyślnie na 2 zespoły;
- Możliwość usunięcia osoby z listy;
- Jakiś interfejs dla "narzędzi". Oprócz dzielenia, dostępne narzędzia powinny obejmować możliwość pobierania wprowadzonych danych w postaci pliku, wgrywania wcześniej zapisanych danych oraz usuwania wszystkich odtwarzaczy za jednym razem;
- Aplikacja powinna pokazywać aktualną liczbę osób „w”;
- Jeśli nie wybrano osób do gry, powinno to ukryć rozdzielanie zespołu;
- Tryb płatności. Przełącznik w ustawieniach, który pozwala użytkownikom „w” mieć dodatkowy przełącznik, aby pokazać, czy zapłacili, czy nie.
Na początku rozważałem cechy produktu o minimalnej opłacalności.
Projekt
Projekty rozpoczęły się na skrawkach papieru. To było pouczające (czytaj: miażdżące), aby dowiedzieć się, jak wiele pomysłów, które były niewiarygodne w mojej głowie, okazały się absurdalne, gdy poddano je nawet skromnej analizie, jaką zapewniał rysunek ołówkiem.
Wiele pomysłów zostało więc szybko odrzuconych, ale drugą stroną było to, że naszkicowanie niektórych pomysłów niezmiennie prowadziło do innych pomysłów, których inaczej nigdy bym nie rozważył.
Projektanci, którzy to czytają, prawdopodobnie powiedzą: „Oczywiście”, ale to była dla mnie prawdziwa rewelacja. Deweloperzy są przyzwyczajeni do oglądania późniejszych projektów scenicznych, rzadko widzą wszystkie porzucone kroki po drodze przed tym punktem.
Kiedy już jestem zadowolony z czegoś takiego jak rysunek ołówkiem, spróbuję odtworzyć go w pakiecie projektowym Sketch. Tak jak pomysły odpadały na etapie papieru i ołówka, taka sama liczba nie zdołała przejść przez kolejny etap wierności Sketch. Te, które wydawały się być obszarami roboczymi w Sketchu, zostały następnie wybrane jako kandydaci do kodowania.
Z kolei odkryłem, że gdy ci kandydaci byli w kodzie wbudowanym, pewien procent również nie działał z różnych powodów. Każdy krok wierności ujawniał nowe wyzwania dla projektu, które mogły przejść lub zakończyć się niepowodzeniem. A porażka doprowadziłaby mnie dosłownie iw przenośni z powrotem do deski kreślarskiej.
Jako taki, ostatecznie projekt, który skończyłem, jest nieco inny niż ten, który pierwotnie miałem w Sketchu. Oto pierwsze makiety Sketch:
Nawet wtedy nie miałem złudzeń; to był podstawowy projekt. Jednak w tym momencie miałem coś, o czym byłem przekonany, że może zadziałać i gryzłem się, aby spróbować to zbudować.
Wymagania techniczne
Mając pewne początkowe wymagania dotyczące funkcji i podstawowy kierunek wizualny, nadszedł czas, aby zastanowić się, co należy osiągnąć za pomocą kodu.
Chociaż uzyskana mądrość podpowiada, że sposobem tworzenia aplikacji na urządzenia z systemem iOS lub Android jest kod natywny, ustaliliśmy już, że moim zamiarem było zbudowanie aplikacji z wykorzystaniem JavaScript.
Zależało mi również na tym, aby aplikacja zaznaczyła wszystkie pola niezbędne do zakwalifikowania się jako Progressive Web Application lub PWA, ponieważ są one bardziej znane.
Jeśli nie wiesz, czym jest progresywna aplikacja internetowa, oto „boisko w windzie”. Koncepcyjnie wyobraź sobie standardową aplikację internetową, ale spełniającą określone kryteria. Spełnienie tego zestawu szczególnych wymagań oznacza, że urządzenie wspierające (pomyśl telefon komórkowy) nadaje aplikacji webowej specjalne uprawnienia, czyniąc aplikację webową większą niż suma jej części.
Zwłaszcza na Androidzie odróżnienie PWA, zbudowanego tylko za pomocą HTML, CSS i JavaScript, od aplikacji zbudowanej za pomocą kodu natywnego może być prawie niemożliwe.
Oto lista kontrolna wymagań Google, aby aplikacja była uznawana za progresywną aplikację internetową:
- Witryna jest obsługiwana przez HTTPS;
- Strony reagują na tablety i urządzenia mobilne;
- Wszystkie adresy URL aplikacji ładują się w trybie offline;
- Metadane przewidziane dla Dodaj do ekranu głównego;
- Pierwsze szybkie ładowanie nawet w sieci 3G;
- Witryna działa w różnych przeglądarkach;
- Przejścia stron nie wydają się blokować w sieci;
- Każda strona ma adres URL.
Ponadto, jeśli naprawdę chcesz być pupilem nauczyciela i chcesz, aby Twoja aplikacja była uznawana za „Wzorową progresywną aplikację internetową”, powinna również spełniać następujące wymagania:
- Zawartość witryny jest indeksowana przez Google;
- Metadane Schema.org są dostarczane w stosownych przypadkach;
- Metadane społecznościowe są dostarczane w stosownych przypadkach;
- W razie potrzeby podawane są kanoniczne adresy URL;
- Strony używają History API;
- Treść nie przeskakuje podczas ładowania strony;
- Naciśnięcie wstecz ze strony szczegółów zachowuje pozycję przewijania na poprzedniej stronie listy;
- Po dotknięciu dane wejściowe nie są zasłaniane przez klawiaturę ekranową;
- Zawartość można łatwo udostępniać w trybie autonomicznym lub pełnoekranowym;
- Witryna reaguje na wszystkie rozmiary ekranu telefonu, tabletu i komputera stacjonarnego;
- Wszelkie monity dotyczące instalacji aplikacji nie są nadmiernie wykorzystywane;
- Monit Dodaj do ekranu głównego zostaje przechwycony;
- Pierwsze ładowanie bardzo szybkie, nawet w 3G;
- Witryna korzysta z sieci opartej na pamięci podręcznej;
- Witryna odpowiednio informuje użytkownika, gdy jest on offline;
- Podaj kontekst użytkownikowi, w jaki sposób będą używane powiadomienia;
- Interfejs użytkownika zachęcający użytkowników do włączania powiadomień push nie może być nadmiernie agresywny;
- Witryna przyciemnia ekran, gdy pojawia się prośba o pozwolenie;
- Powiadomienia push muszą być terminowe, precyzyjne i trafne;
- Zapewnia kontrolę włączania i wyłączania powiadomień;
- Użytkownik jest zalogowany na różnych urządzeniach za pośrednictwem interfejsu Credential Management API;
- Użytkownik może łatwo płacić za pośrednictwem natywnego UI z Payment Request API.
Crikey! Nie wiem jak wy, ale ta druga porcja rzeczy wydaje się być ogromem pracy dla podstawowej aplikacji! Tak się składa, że jest tam mnóstwo rzeczy, które i tak nie pasują do tego, co zaplanowałem. Mimo to nie wstydzę się powiedzieć, że spuściłem celowniki, by zdać tylko wstępne testy.
Uważam, że dla całej sekcji typów aplikacji PWA jest rozwiązaniem bardziej odpowiednim niż aplikacja natywna. Tam, gdzie gry i SaaS prawdopodobnie mają więcej sensu w sklepie z aplikacjami, mniejsze narzędzia mogą żyć w sieci całkiem szczęśliwie i z większym powodzeniem jako progresywne aplikacje internetowe.
Podczas gdy w temacie uchylałem się od ciężkiej pracy, innym wyborem dokonanym na początku była próba przechowywania wszystkich danych dla aplikacji na własnym urządzeniu użytkownika. W ten sposób nie byłoby konieczne łączenie się z usługami danych i serwerami oraz zajmowanie się logowaniem i uwierzytelnianiem. Bo gdzie były moje umiejętności, ustalenie uwierzytelniania i przechowywanie danych użytkownika wydawało się, że prawie na pewno będzie to gryzło więcej, niż mógłbym przeżuć i przesadzić dla zakresu aplikacji!
Wybór technologii
Mając dość jasne wyobrażenie o tym, jaki jest cel, zwrócono uwagę na narzędzia, które można wykorzystać do jego zbudowania.
Wcześnie zdecydowałem się użyć TypeScript, który jest opisany na jego stronie internetowej jako „… typowany nadzbiór JavaScript, który kompiluje się do zwykłego JavaScript”. To, co widziałem i czytałem o języku, który mi się podobał, a zwłaszcza o tym, że tak dobrze nauczył się do analizy statycznej.
Analiza statyczna oznacza po prostu, że program może spojrzeć na Twój kod przed jego uruchomieniem (np. gdy jest statyczny) i wskazać problemy. Niekoniecznie może wskazywać na problemy logiczne, ale może wskazywać na kod niezgodny z zestawem reguł.
Wszystko, co mogłoby wskazać moje (z pewnością wiele) błędów, musiało być dobre, prawda?
Jeśli nie znasz języka TypeScript, rozważ następujący kod w waniliowym JavaScript:
console.log(`${count} players`); let count = 0;
Uruchom ten kod, a otrzymasz błąd podobny do:
ReferenceError: Cannot access uninitialized variable.
Dla tych, którzy mają choć trochę biegłości w JavaScript, w tym podstawowym przykładzie nie potrzebują narzędzia, które by im powiedziało, że rzeczy nie zakończą się dobrze.
Jeśli jednak napiszesz ten sam kod w TypeScript, dzieje się tak w edytorze:
Dostaję informację zwrotną na temat mojego idiotyzmu, zanim jeszcze uruchomię kod! Na tym polega piękno analizy statycznej. Ta informacja zwrotna często przypominała bardziej doświadczonego programistę, który siedział ze mną i wyłapywał błędy.
TypeScript przede wszystkim, jak sama nazwa wskazuje, pozwala nam określić „typ” oczekiwany dla każdej rzeczy w kodzie. Zapobiega to nieumyślnemu przekształceniu jednego typu w inny. Lub próba uruchomienia metody na fragmencie danych, który nie ma zastosowania — na przykład metoda tablicowa na obiekcie. Nie jest to coś, co koniecznie skutkuje błędem podczas działania kodu, ale z pewnością może wprowadzić trudne do śledzenia błędy. Dzięki TypeScript otrzymujesz informację zwrotną w edytorze jeszcze przed próbą uruchomienia kodu.
TypeScript z pewnością nie był niezbędny w tej podróży odkrywczej i nigdy nie zachęcałbym nikogo do korzystania z narzędzi tego rodzaju, chyba że byłaby wyraźna korzyść. Konfigurowanie i konfigurowanie narzędzi w pierwszej kolejności może być stratą czasu, więc zdecydowanie rozważ ich zastosowanie przed nurkowaniem.
Istnieją inne korzyści zapewniane przez TypeScript, o których powiemy w następnym artykule z tej serii, ale same możliwości analizy statycznej wystarczyły, abym chciał zaadoptować TypeScript.
Dokonywane przeze mnie wybory wiązały się z dopingiem. Decydując się na budowanie aplikacji jako progresywnej aplikacji internetowej oznaczało, że musiałem do pewnego stopnia zrozumieć Service Workerów. Korzystanie z TypeScript oznaczałoby wprowadzenie pewnego rodzaju narzędzi do budowania. Jak zarządzać tymi narzędziami? Dawniej używałem NPM jako menedżera pakietów, ale co z Yarn? Czy warto było zamiast tego używać przędzy? Skupienie się na wydajności oznaczałoby rozważenie niektórych narzędzi minifikacji lub łączenia; narzędzia takie jak webpack stawały się coraz bardziej popularne i wymagały oceny.
Streszczenie
Rozpoznałem potrzebę podjęcia tej wyprawy. Moje zdolności JavaScript były słabe i nic tak nie opasuje lędźwi jak próba zastosowania teorii w praktyce. Decyzja o zbudowaniu aplikacji webowej z waniliowym JavaScriptem miała być moim chrztem ognia.
Poświęciłem trochę czasu na badanie i rozważanie opcji tworzenia aplikacji i zdecydowałem, że uczynienie aplikacji progresywną aplikacją internetową jest najbardziej sensowne dla moich umiejętności i względnej prostoty pomysłu.
Potrzebowałem narzędzi do budowania, menedżera pakietów, a następnie całej masy cierpliwości.
Ostatecznie w tym miejscu pozostało podstawowe pytanie: czy to było coś, czym naprawdę mogłem sobie poradzić? A może upokorzy mnie moja własna nieudolność?
Mam nadzieję, że dołączysz do mnie w części drugiej, kiedy będziesz mógł przeczytać o narzędziach do budowania, wzorcach projektowych JavaScript i sposobach tworzenia czegoś bardziej „aplikacyjnego”.