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 lekcji pokażę ci, w jaki sposób eksperymentować z Node za pomocą interfejsu REPL, czyli Read Eval Print Loop.
Na tym etapie zakładam, że masz już zainstalowane środowisko Node w swoim systemie.
Jeżeli miałeś wcześniej i pominąć lekcje, w których pokazałem, jak zainstalować Node w różnych systemach
operacyjnych, to jedyne, co powinieneś zrobić, to upewnić się, że masz przynajmniej taką wersję, jak ja.
W moim przypadku jest to 6.7.0, więc jeżeli masz taką wersję lub nowszą, to wszystko ok.
Jeżeli masz starszą wersję, to proszę, zaktualizuj do najnowszej wersji Node.
Od tej pory już do końca tego kursu będziemy posługiwali się terminalem (w moim przypadku). W Windowsie
jest to wiersz poleceń.
Jeżeli nie znasz podstawowych komend, które są potrzebne, aby poruszać się w takim środowisku, to pod tym
adresem możesz na blogu eduweb.pl znaleźć tutoriale wideo, w których pokazuję takie podstawowe właśnie komendy
zarówno dla Windowsa, jak i dla Maca czy też Linuksa.
Dlatego że Mac i Linux tutaj niewiele się różnią.
Ok, zacznijmy sobie poznawanie tego interfejsu REPL. Jestem w terminalu i w dowolnym miejscu jakby w strukturze
plików, czyli nie muszę do żadnego katalogu przechodzić konkretnie, mogę wpisać node i wcisnąć Enter. I w
tym momencie pojawiła się strzałeczka z lewej strony, więc widzisz, że jesteśmy w jakimś nowym środowisku.
I to jest właśnie interfejs REPL, z którego możemy sobie skorzystać, aby eksperymentować z Node. Wiesz już,
że Node.js jest to platforma, która potrafi interpretować język JavaScript, a więc jeżeli wpiszę tutaj
2+2 - jest to poprawny kod JavaScript - wcisnę Enter, to pojawiła się czwórka, czyli wynik takiego
dodawania.
Być może widzisz już pewne podobieństwa do konsoli przeglądarkowej, do której możemy przejść np. w przeglądarce
Google Chrome. Będąc na dowolnej stronie, możesz wcisnąć prawym przyciskiem, wybrać Inspect czy Zbadaj
i przejść do zakładki Console.
Tutaj podobnie będę sobie mógł wpisać 2+2 i wynik tak jak w tamtym przypadku jest to 4.
Może tutaj trochę powiększę, aby było to lepiej widoczne.
Czyli możemy sobie tutaj wykonywać dowolny kod JavaScript.
W przypadku konsoli w przeglądarce będzie on wykonywany w obrębie strony, na której się znajdujemy.
A tutaj w przypadku Node będzie on wykonywany w takim środowisku Node.
Czym te dwa środowiska się różnią?
Już postaram ci się wytłumaczyć.
Jeżeli przerabiałeś moje poprzednie kursy JavaScript, szczególnie kurs JavaScript od podstaw, to zapewne
pamiętasz, że tam wyraźnie stawiałem linię w miejscu, w którym jakby kończy się JavaScript, ten znany nam ze specyfikacji
ECMAScript, a gdzie zaczynają się API przeglądarek internetowych.
Oznacza to tylko tyle, że specyfikacja ECMAScript definiuje pewien zestaw funkcji, które są w języku
JavaScript dostępne, a wszystkie inne, z których korzystamy w przeglądarkach, są tam tylko dlatego, że przeglądarki
dodają do JavaScript swoje API.
Podobnie będzie w przypadku Node.
Zobaczmy, jak to działa w praktyce.
Jeżeli tutaj w konsoli Node wpiszę sobie parseInt - jest to funkcja znana nam z JavaScript i jest ona w specyfikacji
ECMAScript - np. 2a.
Podam taki string, to dwójka została zwrócona. I teraz jeżeli dokładnie taką samą instrukcję chciałbym
wywołać tutaj w przeglądarce, to mamy dokładnie ten sam rezultat, czyli interpreter JavaScript,
i w tym przypadku jest to dokładnie ten sam interpreter, czyli silnik V8 tutaj w Chrome i silnik
V8 tutaj w Node, wykonał nam taki kod JavaScript i zwrócił wynik.
Teraz spróbujmy wykonać sobie console.log. Wpiszę wiadomość, wciskam Enter i widzimy, że w Node możemy korzystać
z console.log. Teraz spróbujmy tego samego w przeglądarce internetowej. I mamy dokładnie ten sam efekt,
czyli wiadomość została wyświetlona i tutaj ta funkcja zwróciła undefined.
Co jest jednak ciekawe?
Być może o tym wiesz, to console nie jest zapisane w specyfikacji ECMAScript,
czyli tak naprawdę nie ma tego w czystym
można powiedzieć JavaScript, ale przeglądarki udostępniają nam taki obiekt ze swoimi metodami. I podobnie
jest w Node. Chociaż w samym silniku V8
można powiedzieć, że nie ma takiego zapisu jak console.log, to jest to dodane poprzez API Node.js, abyśmy mogli
z tego korzystać w taki sam sposób jak w przeglądarkach internetowych.
Co jednak jeżeli chciałbym skorzystać z funkcji alert, która jest dostępna na stronach internetowych
poprzez język JavaScript?
Możemy wpisać alert i tutaj np. hej! Widzimy, że okienko alert nam się wyświetliło.
Teraz spróbujmy skorzystać z dokładnie takiego samego zapisu tutaj, w Node.js.
No i pojawia się błąd ReferenceError - alert is not defined. Czyli tutaj w Node nie ma takiej funkcji jak
alert.
Powód jest dokładnie taki sam.
Otóż w specyfikacji ECMAScript nie ma czegoś takiego jak alert. Node również sobie tego nie zaimplementował, bo
nie potrzebuje takiej funkcji, ale przeglądarki taką funkcję sobie implementacją poprzez swoje API, a
dla nas jest ona dostępna z poziomu języka JavaScript.
Wszystkie funkcje, które są globalne, zawsze pochodzą z jakiegoś globalnego obiektu.
Tak to działa w JavaScript, a więc jeżeli możemy tutaj bezpośrednio wpisać alert, to znaczy, że również możemy wpisać jakiś
obiekt globalny i po kropce się odwołać do alert.
Zapewne wiesz, że w przeglądarkach mamy obiekt globalny, którym jest window. On zawiera bardzo wiele
metod i właściwości, na przykład do pracy z obiektowym modelem dokumentu.
Ale jeżeli bym sobie zamiast tego alert, wpisał window.alert, to efekt będzie dokładnie taki
sam.
I teraz możemy sprawdzić, czy w Node - tutaj sobie ekran wyczyszczę - mamy coś takiego jak window. Wpiszę window i
po raz kolejny mamy window is not defined. ReferenceError.
Czyli znowu w przypadku Node taki obiekt jak window nie istnieje.
W Node istnieje natomiast obiekt, który znajduje się pod zmienną global. Mogę wpisać global, wcisnąć Enter.
I tutaj bardzo wiele różnych rzeczy nam się wyświetli.
Na przykład taka funkcja jak setTimeout, którą możemy znać z przeglądarek. Skoro ona jest pod global
w moim przypadku - tak jak tutaj to wpisałem w Node - to znaczy, że również możemy z niej korzystać. W przypadku
przeglądarki ona będzie pod window też gdzieś dostępna, czyli będziemy mieli window.setTimeout i
znowu funkcja setTimeout nie jest w specyfikacji ECMAScript, ale zarówno Node, jak i API przeglądarek ją
implementują. Wyczyszczę sobie ekran raz jeszcze i teraz chciałbym ci pokazać kolejną rzecz. Mianowicie na co kieruje
w przeglądarce this.
Jeżeli wpiszemy samo this, to kieruje to na window, dlatego mogę wpisać this i porównać to do obiektu window.
Tutaj zostanie zwrócone true.
A to oznacza, że this kieruje dokładnie w to samo miejsce, co zmienna window. I teraz co w tym przypadku
jest pod this? Wpiszmy sobie this i mamy to, co widziałem przed momentem.
A to oznacza, że this równa się global.
Mamy tutaj wartość true. Czyli abyś to dobrze zrozumiał,
w przypadku języka JavaScript zawsze musimy mieć jakiś obiekt globalny. I w przeglądarkach jest to
window, który zawiera różne metody i właściwości, a w przypadku Node ten obiekt globalny to obiekt global,
a dokładnie taka zmienna do niego kieruje. I on ma swoje właściwości i swoje metody, które wcale nie muszą
się pokrywać z tym, co widzimy w przeglądarkach internetowych.
To są dwa osobne środowiska.
Możemy to udowodnić w prosty sposób. Jeżeli sobie tutaj wpiszę process, to mamy taką zmienną jak process i pod
nią jest bardzo wiele różnych właściwości i metod.
W jednej z kolejnych lekcji będziemy process omawiać. To znaczy, że mogę również wpisać global.process i
będzie to dokładnie to samo.
Natomiast tutaj nie mogę wpisać window.process, bo będziemy mieli wartość undefined.
To oznacza, że taka zmienna process w przypadku przeglądarki nie jest zaimplementowana, a gdyby była, to
prawdopodobnie znaczyłaby zupełnie coś innego. Jak zatem widzisz, zarówno przeglądarka Chrome, jak i
Node.js zawierają w sobie silnik V8, który interpretuje kod JavaScript, ale on robi to zgodnie ze specyfikacją
ECMAScript, czyli tutaj i tutaj mamy na przykład taką funkcję jak parseInt.
Wszystkie inne funkcje, które nie znajdują się w specyfikacji, są poprzez specjalne API dopisane do tego
silnika V8.
I one są różne w Node i różne w przeglądarkach internetowych dla swoich potrzeb.
Skąd to wszystko się bierze i w jaki sposób do Node można dopisać swoje moduły?
Pokażę ci to później w tym kursie, abyś jeszcze lepiej mógł to zrozumieć.
Natomiast na koniec chciałbym ci w tym interfejsie REPL, który służy do eksperymentowania, pokazać jeszcze
kilka komend.
Otóż możemy po kropce wpisywać sobie pewne komendy. I możemy wpisać help i zobaczymy tutaj wszystkie
komendy, z jakich można korzystać, na przykład break i każdą z nich poprzedzamy kropką, tak jak to zrobiłem
przed momentem.
Podobnie możesz je zobaczyć na stronie dokumentacji Node.js.
Tutaj, wraz z opisami.
Jedną z ciekawszych metod jest editor. Możemy tutaj wpisać editor i przechodzimy do takiego edytora, który
pozwala nam pisać w wielu linijkach.
Więc mogę utworzyć sobie funkcję w ten sposób i w nowej linii kontynuować.
I teraz zakończę tę funkcję i Ctrl+D, aby z tego wyskoczyć. I teraz w naszej przestrzeni globalnej będzie
taka funkcja jak f, którą mogę sobie wywołać.
I tutaj widzimy jej rezultaty.
Aby opuścić taki interfejs REPL, wpisujemy .exit i teraz wyskoczyliśmy tutaj w konsoli do miejsca, w którym
wpisywaliśmy wcześniej polecenie node, aby do tego REPL wejść. Na sam koniec ciekawy trik.
Otóż może najpierw wyczyszczę ekran. Jeżeli w pustej linijce wciśniesz Tab, to zostaną wyświetlone wszystkie
globalne zmienne, z których można korzystać. Ale wejdźmy z powrotem do tego interfejsu.
Tutaj wciskam Tab i możesz zobaczyć wszystko, co jest w globalnej przestrzeni, np. array, date itd. Czyli to, co
znamy z JavaScript, jest tutaj wyświetlane. Ale oprócz tego jeszcze wiele innych rzeczy, których jeszcze nie
znasz, a które są dostępne w Node, takich jak np. child_process czy assert. To są moduły Node, z których możemy korzystać.
Natomiast ta lista, która jest tutaj, pokazuje nam, jakie są globalne zmienne, z których bezpośrednio w
tym interfejsie REPL korzystać można.
Na koniec wyjdziemy, raz jeszcze wpisując exit, wyczyszczę ekran i na tym zakończymy tę lekcję. A w kolejnej
lekcji pokaże ci już, jak stworzyć swój pierwszy skrypt w Node.js, który będzie w osobnym pliku
i który będziemy mogli uruchomić z poziomu właśnie wiersza poleceń.