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 pokażę ci, w jaki sposób możemy aktualizować moduły zarówno lokalne, jak i globalne
z użyciem npm.
Mam tutaj już w folderze plik package.json, który utworzyłem, wpisując npm init.
I po prostu wciskając Enter do samego końca. I mamy plik index, który korzysta z modułu del, tak jak mieliśmy
dwie lekcje wcześniej.
Nie będziemy tutaj nic usuwać i tak naprawdę z niego korzystać, ale go sobie tutaj importujemy.
Więc jeżeli bym sobie wykonał node index, to zobaczymy teraz błąd, bo nie pobrałem jeszcze tego modułu.
Chcę go zatem zainstalować, czyli wpiszemy npm install, następnie save, ale jeszcze wcześniej dopiszemy
sobie tutaj del.
To pokazywałem ci dwie lekcje temu, czyli ten moduł zostanie zainstalowany i dopisany do pliku package.json.
Ten plik znajduje się w tym miejscu. Ok.
Został tutaj dopisany.
Natomiast teraz chcę ci pokazać, jak można moduły aktualizować. Ale ta wersja jest najnowsza, więc nam się
to nie uda, więc z tego powodu chciałbym zainstalować wersję, która jest trochę starsza.
Zrobimy to, wpisując npm install del@2.2.0.
W ten sposób. Save. Ok. To też już ci pokazywałem.
Teraz powinniśmy mieć taką wersję właśnie 2.2.0 tutaj.
No i teraz pokażę ci, w jaki sposób możemy zaktualizować.
Z jakiego powodu tak się dzieje?
Otóż przed momentem jeżeli zainstalowałem wersję najnowszą - było to 2.2.2, no i teraz powiedzmy, że pracuję
nad jakimś projektem przez tydzień, dwa, może miesiąc albo wrócę do niego za pół roku,
no to logiczne jest, że te najpopularniejsze moduły będą miały już swoje nowe wersje. Więc będę chciał
do tych nowych wersji je zaktualizować. I aktualizacja jest bardzo prosta, bo wystarczy że wpiszemy
npm update. Natomiast aby zostało to zaktualizowane i dopisane tutaj, to znowu musimy skorzystać z save.
Natomiast gdybyś najpierw chciał sprawdzić, które moduły są nieaktualne i mówię moduły tylko z tego powodu,
że ich tutaj możemy mieć dużo więcej. Jeżeli w naszej aplikacji nie będziemy korzystać wyłącznie z del,
ale jeszcze z wielu innych, to możemy wpisać npm outdated. Tutaj powinno nam zostać wyświetlone, który
jest nieaktualny - dokładnie moduł del.
Mamy wersję 2.2.0, a wersja, którą powinniśmy mieć, czyli wanted, jest to 2.2.2, i najnowsza również jest
taka wersja.
Więc jeżeli wpiszę npm update save, to powinniśmy mieć najnowszą wersję i oprócz tego, że najnowszą wersję,
to jeszcze powinno to zostać dopisane tutaj.
Tak zatem wygląda praca właśnie z takim plikiem package.json i z modułami. Ja do projektów, które piszę w Node,
do których wracam, to kiedy otwieram, to po prostu wpisuję sobie npm update po to, aby od razu zaktualizować
sobie moduły do najnowszych wersji.
Zauważ, że tutaj nic się nie zmienia.
Polecenie outdated działa również na modułach globalnych. Czyli globalne moduły w systemie to np. nodemon, który
ci pokazałem, czy jshint. Więc mogę sobie wpisać npm outdated -g
i pokaże mi moduły, które mam w systemie globalnie zainstalowane, które są nieaktualne.
No i zauważ, że pokazało mi np. że npm ma trochę nowszą wersję. Ale w przypadku niektórych np. browser sync
mam pokazane, że ja mam zainstalowaną taką wersję, taką wersję powinienem chcieć, ale jest też nowsza
wersja, która wygląda w ten sposób. Ona może mieć jakieś rzeczy, które są teoretycznie eksperymentalne,
chociaż w przypadku wersji, która tak wygląda, tak być nie powinno.
A dlaczego? To teraz chciałbym ci powiedzieć.
Oczywiście gdybym te moduły chciał zaktualizować, to też mogę wpisać npm update, tak jak ci pokazywałem
przed momentem, ale dopisując g. Wtedy nie aktualizuję tych, które są w tym katalogu, w którym jestem,
ale te, które są globalnie.
Ja oczywiście czasami sobie tak robię, bo skoro mam nodemona i inne zainstalowane, to raz na jakiś
czas warto wpisać npm update -g, aby pobrać sobie ich najnowsze wersje.
Natomiast zauważ jedną rzecz, że mając teraz tutaj del w tych dependencies, mamy zapisaną wersję 2.2.2
z takim daszkiem na początku. I chciałbym ci teraz powiedzieć, na czym to polega.
Otóż wszystkie moduły, które znajdują się w repozytorium npm, powinny - bo wcale nie muszą,
nie da się tego sprawdzić, ale twórcy, którzy je tworzą, bo my też możemy je tworzyć - powinny brać pod uwagę
tzw. semantic versioning czy być wersjonowane właśnie zgodnie z taką semantyką. Semantic versioning znajdziesz
na stronie semver.org.
Natomiast jest to bardzo proste. Chcę ci to już wytłumaczyć.
Wyobraź sobie, że ty wypuszczasz jakiś swój projekt i nazwiesz go wersją 1.0.0. To teraz to, co jest istotne,
będziemy mieli x.x.x, to ten pierwszy x
jest to major, czyli duża zmiana.
Drugi jest to minor, czyli nieduża zmiana - czyli mniejsza taka zmiana.
I trzeci jest to patch.
Dokładnie to samo możesz przeczytać tutaj, ale ja ci to teraz szybko wytłumaczę.
Wyobraź sobie, że zrobiłeś jakieś zmiany w tym programie, który wypuściłeś, czy w twoim skrypcie,
czy w szablonie -
nie ma znaczenia. Ważne, że tworzysz jakieś oprogramowanie z użyciem semantic versioning.
Jeżeli tylko coś poprawiłeś, bo znalazłeś jakieś błędy, to zmieniasz ostatni x,
czyli patch. W ten sposób - np. 1.0.1. i wypuszczasz kolejną wersję.
To mówi wszystkim, którzy z niej będą korzystać, że jeżeli korzystali z poprzedniej wersji, to mogą śmiało
zaktualizować do twojej wersji
i nic im się w kodzie nie popsuje, bo ty tylko coś naprawiłeś.
Jeżeli dodasz jakieś funkcjonalności, ale w sposób wstecz kompatybilny, czyli np. w przypadku del jeżeli
z jakichś metod, gdyby tu były jakieś metody, gdybyśmy z nich korzystali i ktoś wypuści nową wersję w ten sposób,
że nasz kod napisany poniżej nadal będzie działał i się nie rozsypie, po prostu dodał jakieś nowe funkcje,
ale w sposób kompatybilny wstecz, to zmieniasz sobie tutaj wersję.
Czyli mieliśmy wersję 1.0.1.
Dodałem jakieś fajne funkcje, które niczyjego kodu nie zepsują, ale może z nich skorzystać, to zmieniam sobie
to w ten sposób i mamy wersję 1.1.0.
Natomiast jeżeli dodam jakieś rzeczy, które spowodują, że czyjś kod korzystający z mojego modułu może
być niekompatybilny, bo są to nowe rzeczy, jakaś nowa wersja, to wtedy zmieniam major, czyli to, co jest
na początku i wypuszczam np. wersję 2.0.
Dlatego jeżeli cały czas będę rozwijał swój moduł w taki sposób, że niczego u nikogo nie popsuję, to mogę mieć
nawet taką wersję, mogę mieć - nie wiem - 1.19.2 itd.,
nigdy nie przechodząc do wersji 2.0.0. I teraz dlaczego o tym mówię?
Dlatego że zakładając, iż moduł del korzysta z semantic versioning, to ten daszek na początku, który tutaj został
przez npm dodany, oznacza, że kiedy my sobie tutaj będziemy wpisywać npm update, to npm zadba o
to, abyśmy nigdy nie przeskoczyli do wersji 3.0.0. Czyli taki daszek mówi, że może być zmieniony major, a w zasadzie
minor - przepraszam. Bo to jest major, minor i patch, więc to może być zmienione i to może być zmienione.
A oznacza to tylko tyle, że zawsze z przodu będzie dwójka i zgodnie z tym semantic versioning będzie to
zawsze wstecz kompatybilne.
Natomiast gdybyś chciał zmienić to sobie w ten sposób, że podasz tutaj tyldę, to będzie to jeszcze bardziej
restrykcyjne, bo jeżeli mamy wersję 2.2.2, to z taką tyldą za każdym razem kiedy wpiszemy npm update, to
nie pozwoli nam npm zainstalować nowszej wersji niż tylko zmieniony patch. Czyli tutaj nigdy nie
pojawi się trójka. 2.3.0 nie będzie możliwe do zainstalowania. Jeżeli mieliśmy 2.2.2, to może być 2.2.3 itd.,
czyli tylko ten ostatni x może się zmieniać.
Wróćmy sobie jednak do tej postaci i na tym możemy zakończyć tę lekcję.
Chciałem tylko, abyś rozumiał, na czym polega semantic versioning. Czyli podsumowując, ostatnia cyfra to tylko
jakiś patch, jakieś poprawki, back fixy.
Wersja, która jest na środku, to jest jakaś nowa funkcjonalność, ale wstecz kompatybilna. A wersja z przodu
są to nowe, niekompatybilne wstecz funkcjonalności. Zapamiętaj z tej lekcji tylko tyle, że co jakiś czas,
kiedy tworzysz swój projekt, wpisz sobie npm update, aby ściągnąć najnowsze wersje albo sprawdź je najpierw
poprzez npm outdated. Podobnie zrób z modułami globalnymi, wpisując npm update -g, aby raz na jakiś czas
pobrać sobie ich nowe wersje.