w Praktyce
10 godz. 44 min · Node.js · Full-stack i Programowanie
Piotr PalarzWeb DeveloperW kursie tym poznasz platformę Node.js od podstaw, aż po bardziej zaawansowane koncepcje. Zaczniemy od omówienia czym jest Node, a także jakie może być zastosowanie tej technologii. Następnie przejdziemy przez proces instalacji i napisanie swojego pierwszego skryptu. Już na samym początku dokładnie omówimy tworzenie własnych modułów, gdyż jest to wiedza niezbędna, by dobrze zrozumieć funkcjonowanie Node. Następnie dowiesz się czym są zdarzenia, jak działa model “publish / subscribe”, a także czym jest “event-driven development”. Chwilę później omówimy pracę z buforami, stream’ami, a także ze standardowym wejściem i wyjściem. Ta wiedza pozwoli Ci zrozumieć jak tworzone aplikacje mogą otrzymywać od użytkownika dane oraz jak je wyświetlają.
Niezwykle ważnym rozdziałem będzie ten, poświęcony pracy z systemem plików. Szczególnie dla dewelopera, pracującego dotychczas z językiem JavaScript wyłącznie w środowisku przeglądarki internetowej. Node pozwala bowiem tworzyć nowe pliki, zapisywać w nich dane oraz odczytywać i usuwać pliki i katalogi. Przy wszystkich tych operacjach, niezwykle ważna jest jednak asynchroniczna natura Node. Dowiesz się jak działa, a także jakie są jej zalety. Na tym etapie nie zabraknie oczywiście praktycznego projektu, którym będzie aplikacja typu CLI (Command Line Interface). Pozwoli nam ona grupowo zmienić nazwy wielu plików, według podanego wzorca.
W kolejnym rozdziale poruszymy fundamentalną dla Node kwestię, mianowicie tworzenie serwerów sieciowych. Zaczniemy od najniższego poziomu, tworząc prosty serwer bazujący na protokole TCP/IP. Wiedza w jaki sposób Node radzi sobie z takim zadaniem, pozwoli później lepiej zrozumieć wyższe warstwy, takie jak np. HTTP czy WebSockets. Chwilę później stworzymy swój pierwszy serwer HTTP, do którego będzie można wysyłać zapytania wprost z przeglądarki internetowej. Omówimy również jak w Node wykorzystać bezpieczne szyfrowanie HTTPS.Na tym etapie będziesz już miał solidną wiedzę jak pracować z Node, jednak zanim przejdziemy dalej, zatrzymamy się, by omówić jak dokładnie działa Node.js, a także jak ta platforma została zbudowana. Dwie dość obszerne lekcje, będą być może jednymi z najważniejszych w tym kursie. Dowiesz się w nich czym jest, a także jak działa jednowątkowa pętla zdarzeń, czym jest proces i wątek, a także zobaczysz kod źródłowy Node.js i wszystkie bloki budulcowe, z jakich Node się składa. To naszym zdaniem niezwykle ważny temat, często jednak pomijany w wielu materiałach. Dzięki dogłębnemu zrozumieniu jednowątkowej natury języka JavaScript i asynchroniczności Node, będziesz mógł tworzyć dużo lepsze aplikacje.
Node.js posiada kilkanaście wbudowanych modułów, z których w dowolnej chwili można skorzystać. Wszystkie jednak dają nam dużą, niskopoziomową kontrolę, ale czasami sporo kodu należy napisać, by zrealizować jakieś zadanie. Jest to jednak świadomy wybór twórców Node, gdyż całą resztę świetnych rozwiązań, dopisuje nieustannie ogólnoświatowa społeczność deweloperów. Zdecydowana większość z modułów ląduje w rejestrze npm. Jest to genialny package manager, który pozwoli nam wyszukiwać, pobierać i aktualizować niezliczoną ilość modułów. Dowiesz się zatem jak korzystać z npm, a chwilę później zaczniemy wykorzystywać zgromadzone tam moduły w dalszej pracy.Jednym z najpopularniejszych modułów jest express.js, który pozwala w bardzo prosty sposób tworzyć serwery HTTP. Grzechem byłoby zatem z niego nie skorzystać. Dowiesz się wszystkiego co niezbędne, by zacząć tworzyć własne aplikacje bazujące na protokole HTTP z użyciem express.js, a także kilku dodatków do tego systemu. Zobaczysz jak routować zapytania, jak korzystać z middleware czy serwować statyczne pliki. Następnie omówimy współpracę z bazą danych MongoDB i z jej wykorzystaniem stworzymy API typu REST. Stworzona aplikacja pozwoli odczytywać dane z bazy i przesyłać je do klienta w formacie JSON, a także dodawać nowe dane, aktualizować i usuwać je. Wszystko to zgodnie z dobrymi praktykami pracy z REST.
Chwilę później czeka Cię kolejny praktyczny projekt - skracacz linków. Stworzymy wspólnie aplikację, która pozwoli skrócić dowolny adres URL do krótkiej formy. Oczywiście będzie działać również w drugą stronę! Kiedy przejdziemy pod skrócony adres, przekieruje nas do odpowiedniej witryny. Node.js to platforma wręcz stworzona do tworzenia aplikacji typu real-time, dlatego w kolejnym rodziale podejmiemy temat technologii WebSockets. Dowiesz się jakie są jej zalety, a także jak pracować z nią po stronie serwera i klienta. Tutaj czeka nas kolejny praktyczny, niezwykle ciekawy projekt. Wykonamy bowiem czat grupowy. Aplikacja ta pozwoli dowolnej ilości użytkowników podłączyć się do czatu podając swój nick, a następnie wysyłać widoczne dla wszystkich wiadomości. Zaimplementujemy nawet takie rozwiązania jak wyświetlanie statusów o dołączeniu kogoś do czatu, a także o jego opuszczeniu.W przedostatnim rodziale tego kursu podejmiemy tematykę dobrych praktyk pracy z Node.js. Na początku omówimy najważniejsze konstrukcje nowej specyfikacji EcmaScript 2015, które są znakomicie wspierane w Node. Chwilę później omówimy jak korzystanie z Promises uprości, a także ulepszy nasz kod. Wśród dobrych praktyk nie zabraknie również informacji o debugowaniu aplikacji. Zobaczysz sprawdzone sposoby, by znaleźć błędy lub lepiej, krok po kroku, zrozumieć jak działa napisany wcześniej kod. Dowiesz się również jak pracować z błędami, by Twoje aplikacje działały w sposób przewidywalny.
Ostatni rozdział w całości został poświęcony temu, co zwykle jest pomijane w innych materiałach, mianowicie wdrażaniu aplikacji do produkcji. Przez cały ten kurs pracować będziemy lokalnie, lecz kiedy aplikacje są już gotowe, wypadałoby udostępnić je światu. Wdrażanie aplikacji napisanych z użyciem Node.js nie jest jednak tak oczywiste, jak np. wgrywanie WordPress’a u wybranego hostingodawcy. Ty będziesz miał jednak możliwość zobaczyć, jak wdrożyć napisany przez nas grupowy czat na platformie Heroku. Jest to bardzo popularny serwis działający jako PaaS (Platform as a Service). Za darmo będziesz mógł w ciągu kilku chwil uruchomić swoją aplikację.Zobaczysz o co należy zadbać, by wszystko poszło gładko. Serwisy typu PaaS dbają o bardzo wiele aspektów wdrażania i serwowania naszych aplikacji, takich jak bezpieczeństwo oraz nieustanną dostępność. Mają jednak pewne ograniczenia. Z tego powodu, dowiesz się również jak wdrożyć swoją aplikację na serwerze wirtualnym VPS z systemem Ubuntu Server. Takie rozwiązanie daje nam całkowitą kontrolę, ale także obarczone jest większą odpowiedzialnością. Zaczniemy od instalacji na serwerze platformy Node.js, systemu kontroli wersji GIT, a także innych niezbędnych modułów
Następnie zobaczysz jak skonfigurować swoje lokalne środowisko tak, by za pomocą GIT’a wysyłać kod do zdalnego serwera, a potem jednym poleceniem wdrażać go do produkcji. Dowiesz się również jak jednocześnie serwować wersję produkcyjną oraz developmencką. W rodziale tym poruszymy również inne kwestie, takie jak procesy potomne czy tworzenie klastrów. Dzięki tej wiedzy, będziesz mógł maksymalnie wykorzystać dostępne zasoby serwera. Na sam koniec tego kursu rzucimy okiem również na inne, nie przedstawione wcześniej zastosowania Node, a także nakreślimy dalszą drogę nauki w tym zakresie.
Kurs ten jest dla wszystkich osób, które dobrze czują się w technologiach frontendowych, tj. HTML, CSS i JavaScript, a teraz chcą rozpocząć swoją przygodę z back-endem. Im zatem lepiej znasz język JavaScript, tym więcej wyciśniesz z Node, natomiast nie jest wymagana bardzo zaawansowana wiedza z zakresu tego języka.
W tej lekcji skorzystamy sobie z biblioteki socket.io, która będzie działać zarówno po stronie serwera, jak
i po stronie klienta.
Jest ona najpopularniejszą biblioteką tego typu. W lekcji poprzedniej pokazałam ci, jak WebSockets można
wykorzystywać na takim niższym poziomie, czyli tak naprawdę takie proste sterowniki i w przeglądarce natywnie.
Natomiast teraz skorzystamy z socket.io.
Pierwsze co chcę zrobić tutaj, to oczywiście zainstalować sobie wszystkie zależności.
Na razie mamy Express i Express Handlebars. I to, co mamy pod index, jest to prosty serwer. Renderuję
sobie tutaj home.
Jedyna różnica, jaką zrobiłem, to jest fakt, że teraz w views > home nie mamy już tego skryptu, który był
w lekcji poprzedniej, ale do partials i do footer dodałem sobie odwołanie do JavaScript, a jego wstawiłem
tutaj do public > js.
Czyli wszystko działa poprawnie,
Skrypt jest dokładnie ten sam. Uruchomimy sobie nodemona. Ok. Wszystko działa, więc odświeżymy sobie
tutaj. Jak widzisz, mamy to samo, co w wersji poprzedniej. Mogę coś wpisać i wyświetlić w console.log, bo jest
to w pliku scripts zapisane w taki sposób.
Natomiast teraz będziemy chcieli skorzystać sobie z biblioteki WebSockets, która nazywa się socket.io. Znajdziesz ją
pod właśnie adresem socket.io. Będziemy chcieli ją pobrać. Tutaj jest pokazane, jak to zrobić.
Ja chcę wersję i kliencką, i na serwer. Czyli na serwer to npm install socket.io. Dlatego serwer Ctrl+C zatrzymam i
ją zainstaluję. Natomiast chcę ją również podłączyć do klienta. Nie będę jej pobierał, tylko z tego cdn-u, z tej
sieci sobie ją załączymy.
Dlatego przejdziemy tutaj i do footer.
W tym miejscu przed naszymi skryptami będę chciał ją wstawić.
Oczywiście można również pobrać i serwować od siebie z serwera.
Będziemy w scripts mogli z niej korzystać, więc na razie jest w porządku. I teraz pokażę ci główną różnicę -
uruchomimy nodemon index - między tą biblioteką a między WebSockets z lekcji poprzedniej. Bo w lekcji poprzedniej uruchamiałem
serwer WebSockets
na innym porcie niż serwer HTTP, np. na porcie 3000, natomiast io działa inaczej.
Najpierw sobie będziemy chcieli tutaj tę bibliotekę zainkludować, ale zrobimy to troszkę niżej. Tutaj.
I tak to będzie wyglądać, czyli require("socket.io") i wywołuje tę funkcję, przekazując jej server.
No i teraz czym jest server?
Dlaczego go tutaj umieściłem?
Jest to niesłychanie ważne.
Otóż musimy sobie utworzyć serwer trochę w inny sposób niż do tej pory.
Jeżeli chodzi o Express, jest to również poprawny sposób, a w przypadku biblioteki socket.io jest on wymagany.
Utworzę sobie stałą server i zrobimy require("http").
Zauważ, że odkąd korzystamy z Expressa, nie korzystaliśmy z http, chociaż Express z niego korzysta później,
pod spodem. I odwołamy się do server i chcę to wywołać. To znaczy, że chcę utworzyć sobie nowy serwer
HTTP, ale przekazując mu aplikacje Expressa. Nie pokazałem ci tego wcześniej, ale dokładnie w taki sposób
można tworzyć aplikacje Expressa. Czyli albo tak, jak my tworzyliśmy, albo utworzyć aplikację i następnie
utworzyć serwer, do którego tę aplikację przekazujemy.
Natomiast to, co jest ważne w przypadku biblioteki io, to właśnie ten serwer musimy przekazać tutaj.
Nie możemy przekazać tam app, bo to nie zadziała.
I druga kluczowa rzecz jest taka, że musimy na końcu nie robić app.listen, ale server.listen.
Jeżeli zrobimy app.listen, serwer HTTP będzie działał, ale WebSockets już nie.
Dlatego to są podstawowe zmiany i teraz będziemy mieli już poprawne połączenie. I będziemy mieli taki
oto serwer. Teraz zrobię rzecz bardzo podobną, jak mieliśmy w lekcji poprzedniej. Mianowicie będę chciał
sobie przypisać do tego naszego io, które mamy tutaj, odpowiednie zdarzenie, dlatego wkleję gotowy
kod.
I zauważ, że znowu mamy metodę on z EventEmittera, connection - tak samo jak w lekcji poprzedniej - przyjmuje to funkcję
i socket.
Tutaj nic się nie zmienia.
Do socketa sobie przypiszemy message i to jest dokładnie to samo.
Natomiast różnica jest później taka, że jeżeli chcemy coś wysłać do niego, to nie mamy metody send, ale
metodę emit i tutaj podajemy jakby nazwę zdarzenia message
i to, co chcemy odesłać. I te nazwy zdarzenia są o tyle istotne, że możemy tutaj sobie wpisywać dowolne
rzeczy.
Czyli mogę go nazwać customowo, np. wiadomość.
Mogę tak zrobić. I po stronie klienta będę mógł nasłuchiwać na wiadomość i wtedy tylko te wiadomości
będą tam przysłane.
Dlatego napiszemy sobie tutaj message, czyli w tym momencie widzimy, że podłącza się do nas jakiś socket i my
przypisujemy do niego takie zdarzenie, że kiedy on coś wyśle do serwera, to my mu to odeślemy za pomocą
socket.emit.
No i teraz pozostało nam po stronie klienta, czyli w pliku, który mamy tutaj - scripts - skorzystać z tego.
Nie będziemy robić new websockets,
tak jak robiliśmy w lekcji poprzedniej - natywnie - ale skorzystamy z biblioteki io, którą dołączyłem do strony.
W zasadzie to nawet po odświeżeniu tutaj zobaczymy, że tak się dzieje.
Mamy bibliotekę socket.io i potem nasze skrypty. I będziemy chcieli z tego skorzystać.
Połączenie będzie wyglądać następująco. Czyli już nie podłączamy się tak jak wcześniej do jakiegoś portu 3000,
tylko dzięki temu, że tutaj uruchomiliśmy io, przekazując mu serwer HTTP, który mamy, to mogliśmy się
do tego podłączyć i dokładnie w taki sam sposób jak podłączamy się do naszego serwera.
Gdybym tutaj w ogóle nie podał tego adresu, to również io powinno znaleźć poprawny adres na podstawie tego,
z jakiego adresu ten skrypt jest pobierany.
No ale zostawmy to w ten sposób. I teraz na socket możemy robić różne rzeczy. I zamiast console.log to
odwołamy się do socket.emit.
Dokładnie tak samo jak na serwerze. Zauważ, jakie to jest proste. Napiszemy message i prześlemy to, co zostało
wpisane w formularzu.
Dlatego po stronie serwera wywoła się tutaj message.
Gdybym tutaj inaczej nazwał to zdarzenie i po stronie serwera zrobił emit z nazwą tego zdarzenia,
to dokładnie to samo zostałoby odesłane. Natomiast z uwagi na fakt, że odsyłam również zdarzenie o nazwie
message, to tutaj możemy na nie nasłuchiwać i zrobimy to w tym miejscu - Socket.on. Tutaj już mamy metodę on, bo
nie korzystamy natywnie tak jak w poprzedniej, gdzie musieliśmy mieć addEventListener.
Tutaj mamy to zwrócone jako obiekt z tej biblioteki, więc możemy dokładnie tak samo jak na serwerze napisać
message.
Bardzo łatwo się z tym pracuje, bo zarówno kod po stronie serwera, jak i klienta jest taki sam i zrobię
console.log po prostu tego message.
Mam nadzieję, że to zrozumiałe dla ciebie, bo nie ma tutaj nic skomplikowanego. Odświeżę. Widzimy tutaj
od razu, że udało się nam podłączyć. Mamy kilka informacji takich ajaxowych i teraz napiszę Witam!,
wyślę. I Witam! nam się odesłało. Żeby przekład był identyczny jak w wersji poprzedniej,
to jeszcze tutaj powinniśmy sobie zrobić console.log(msg).
Teraz już będzie identyczny.
Za każdym razem gdy coś wyślemy, Witam!, to będzie to na serwerze wyświetlane w tym miejscu.
Z tej biblioteki będziemy korzystać jeszcze w lekcji kolejnej, natomiast nie powiedziałem ci o jednej
z najważniejszych rzeczy - dlaczego z niej korzystamy?
Po pierwsze ona ma bardzo wiele ciekawych metod, takich jak np. widzisz nazwane zdarzenia.
Możemy te wiadomości nazywać, jak chcemy, a po drugie, co jest ważniejsze, to ona działa w ten sposób, że
jeżeli będzie ona w przeglądarce, która nie obsługuje WebSockets, czyli teraz jesteśmy w przeglądarce Chrome.
Ona to obsługuje natywnie.
Natomiast jeżeli nie obsługuje, to ta biblioteka w sposób transparentny dla nas będzie wysyłać żądania
typu AJAX, a nawet w skrajnych przypadkach może korzystać z Flasha.
Przynajmniej tak było jeszcze jakiś czas temu.
Teraz nie jestem pewien, czy jeszcze z tego korzysta.
Natomiast my zawsze będziemy z niej korzystać dokładnie w taki oto sposób, a ona pod spodem już sobie
sprawdzi, czy serwer obsługuje WebSockets, czy nie.
Gdyby nie obsługiwał, to będzie to wysyłać AJAX-em przez protokół HTTP, dlatego m.in. tutaj trochę inaczej
musimy wywoływać sobie ten socket.io. W lekcji kolejnej zrobimy z biblioteki świetny użytek, tworząc
praktyczny projekt grupowego czatu.