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.
Choć jesteśmy dopiero na początku drogi nauki Node.js, to chciałbym już teraz poruszyć bardzo ważny temat, mianowicie:
tworzenie własnych modułów.
Jest to jedna z najważniejszych koncepcji w nauce Node.js, dlatego im wcześniej zrozumiesz, jak działają moduły,
tym lepiej dla ciebie. I będziemy z nich korzystać w różnej formie już do końca tego kursu.
Nie przedłużając, zacznijmy od razu tworzyć jakiś kod. Jestem w katalogu 02 i będę chciał w nim utworzyć
plik, który nazwiemy add.js. I on będzie wyglądał następująco.
Wkleję tutaj kod. Nie ma tutaj nic, czego byś nie znał do tej pory,
jeżeli pisałeś w JavaScript. Więc będziemy chcieli zrobić console.log, moduł add.js i stworzyć tutaj funkcję,
która dodaje nam dwie jakieś liczby. Zapiszemy to, ale nie będziemy z użyciem polecenia node wywoływać sobie tego
pliku add.js.
Chociaż oczywiście on się tutaj pojawił, moglibyśmy napisać node add i console.log się pokaże.
My będziemy chcieli ten moduł sobie zaimportować w innym pliku. I stworzymy sobie w tym katalogu 02 kolejny
plik i będzie to main.js, więc 02 main.js.
I tutaj chciałbym sobie zaimportować taki oto moduł, aby móc korzystać z funkcji add.
I teraz na początek możemy utworzyć zmienną, którą dowolnie nazwiemy, np. add i następnie polecenie require.
Jest to funkcja dostępna w każdym pliku.
I tutaj jeszcze ważna uwaga.
W Node.js każdy plik JavaScript jest oddzielnym modułem.
Co się tego tyczy, to m.in. fakt, że każdy z takich plików globalnie ma dostępną funkcję require,
ale nie tylko - o tym powiem za moment.
Czyli teraz będziemy chcieli skorzystać z tej funkcji globalnej require i podać jej ścieżkę do pliku, który
chcemy zaimportować.
Tutaj jest bardzo ważne podawanie poprawnych ścieżek, więc jeżeli jesteśmy w tym samym katalogu, co plik
main.js, to ścieżka będzie wyglądać następująco:
./ i teraz nazwa pliku, czyli np. add.js.
Ale tutaj, podobnie jak w przypadku wywoływania z użyciem polecenia node, nie musimy podawać rozszerzenia.
Domyślnie będzie wyszukiwaniy plik z rozszerzeniem .js, więc w ten sposób możemy sobie zaimportować
ten plik.
Natomiast jeszcze jedna ważna uwaga. Nie musimy tworzyć zmiennej za pomocą var, bo wówczas moglibyśmy
ją napisać pod spodem np. w ten sposób i gdzieś mieć później błąd.
Możemy z użyciem ECMAScript 2015 lub nazywanej też w skrócie ES6 skorzystać z polecenia
czy z takiego słowa kluczowego const, które działa podobnie jak var, z tym że utworzy nam stałą. A zatem
nie będziemy mogli później napisać np. add równa się jeden, bo będziemy mieli błąd.
Wersja 6.5.0 Node, z której ja teraz korzystam, wspiera
ECMAScript 6
w 99%, więc z większości rzeczy możemy korzystać i w tym kursie znajdziesz również osobny dział,
w którym kilka z najważniejszych koncepcji ES6 omówię. Więc my będziemy sobie tworzyć stałe w wielu miejscach,
gdzie będziemy importować moduły za pomocą require
w ten oto sposób. Zapiszmy teraz sobie to wszystko i może jeszcze zrobię console.log i wyświetlimy
add, bo być może jesteś ciekaw, co będzie znajdowało się pod stałą add,
kiedy zaimportujemy sobie taki oto plik. Wywołajmy sobie zatem main tym razem. I po pierwsze zobaczyliśmy console.log,
moduł add.js. Przejdźmy, gdzie to było.
Otóż kiedy wywołaliśmy require add, to Node znalazło sobie tam plik i normalnie wykonało cały kod JavaScript, który
tutaj się znajduje. A więc wykonało również console.log message, stąd mamy ten moduł
add.js, czyli ten log w tym miejscu.
Natomiast później wróciliśmy do tego pliku.
To, co zwrócił nam ten plik, zostało zapisane pod add, no i wykonujemy kolejny console.log, tym razem z
pliku main.
I widzisz, że pod add mamy pusty obiekt.
Jest to taki zwyczajny obiekt.
No i teraz skąd to się tutaj wzięło?
Otóż każdy moduł, a więc każdy plik z rozszerzeniem js, zawiera w sobie nie tylko taką funkcję jak require,
ale również coś takiego jak module.exports.
I jest to pusty obiekt.
To jest domyślnie już przypisane do takiego modułu, czyli w tym momencie ja nadpisałem sobie pusty obiekt,
który tam był, nowym pustym obiektem.
W tym przypadku będziemy mieli efekt dokładnie taki sam w konsoli, ale pamiętaj, że w każdym pliku - i w
tym add.js i również w main - ale
będziemy z tego korzystać w plikach, które są przeznaczone do importowania w innym miejscu,
mamy module.exports i jest to pusty obiekt.
My ten obiekt możemy nadpisać czym tylko chcemy.
W naszym przypadku chcę tutaj podać funkcję add i oczywiście ta funkcja będzie widoczna po drugiej stronie,
czyli w tym przypadku mówię wyeksportuj mi z tego pliku
funkcję add, ale nie wywołuję jej w ten sposób, bo wtedy tutaj przypisałbym to, co ona zwraca, tylko podaję
jej nazwę, czyli przez referencje będziemy na nią kierować.
W ten sposób w tym miejscu require wykona cały ten plik tak jak wcześniej, Node wykona kod JavaScript, który tutaj się znajduje
i na końcu zwróci module.exports, które kieruje na add, więc w tym miejscu będziemy mieli dokładnie tę funkcję.
Moglibyśmy ją nazwać oczywiście inaczej, nie musi się nazywać tak samo jak po tej stronie, ale nazwałem ją
sobie add. Czyli teraz jeżeli sobie zrobimy console.log, to zobaczymy tutaj function.
Czyli jest to już funkcja i mogę z niej skorzystać, podając jej tutaj te parametry, które ona przyjmowała,
czyli jakieś dwie liczby, np. 5 i 6 - powinniśmy w konsoli zobaczyć wynik 11.
Zobaczmy, dokładnie tak też się stało.
Co jest jeszcze bardzo ważne, to my tutaj mamy jakieś zmienne, np. message i są one wyświetlane. Co jeżeli
chcielibyśmy zrobić console.log message w tym pliku, w tym miejscu.
Czy po tym, jak skorzystamy z require add, to wszystkie zmienne z tego pliku będą również w tej przestrzeni czy
też nie.
Zobaczmy.
No i okazuje się, że nie.
Mamy błąd ReferenceError: message is not defined, czyli zmienna message i wszystkie inne zmienne, które
tutaj utworzymy, są prywatne dla tego pliku. Możesz tutaj również utworzyć sobie różne funkcje pomocnicze
dla funkcji, którą wyeksportujesz, i one nie będą widoczne w żadnym innym pliku, a tak byłoby np. w języku PHP,
z którego być może korzystałeś.
Jeżeli tam sobie coś ładowaliśmy poleceniem include, to wszystkie zmienne z jednego pliku przenikały również do
globalnego zakresu w kolejnym pliku.
Jak zatem widzisz, to są podstawy tworzenia własnych modułów. Każdy osobny plik ma funkcję require, bo moglibyśmy
w tym pliku add sobie zaimportować jeszcze inne moduły i później coś wyeksportować oraz każdy z takich plików
ma module.exports, do którego możemy przypisać, co tylko chcemy.
Gdybyśmy tutaj przypisali jakiś obiekt, a w nim np. add i tutaj byłaby jakaś funkcja, bo możemy to zrobić w
ten sposób, to z kolei tutaj kiedy skorzystamy z required, ten obiekt zostałby zwrócony i pod add mielibyśmy taki obiekt
i następnie musielibyśmy po kropce do tego add się odwołać.
Ale bardziej zaawansowane użycie pokażę ci w lekcji kolejnej.