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, jak możemy jeszcze lepiej podzielić sobie swoje moduły na dodatkowe pliki oraz katalogi.
Jesteśmy w przykładzie 03 i w pliku main.js jeszcze nic nie wpisałem, ale zauważ, że mamy tutaj folder, który
nazwałem calculator i w nim mam kilka plików. Przede wszystkim plik add, który już znamy.
Mamy tutaj funkcję do dodawania, ale mamy również podobne funkcje do dzielenia, mnożenia oraz odejmowania.
I to, co jest bardzo ważne - w tym katalogu utworzyłem jeszcze jeden plik, który musi nazywać się
index.js. I w tym pliku
wszystko to sobie zaimportowałem.
Zauważ, że w nim importuję właśnie te poszczególne moduły, a na końcu eksportuję je dodatkowo.
A to oznacza, że tego pliku index.js nie będziemy wywoływać bezpośrednio z terminala, ale również będziemy
go importować w innym miejscu.
Zauważ, że tym razem module.exports nie przypisałem tak, jak w tych innych plikach, np. samej funkcji add,
ale tutaj stworzyłem nowy obiekt. I w tym obiekcie właściwości takie jak add, subtract, multiply i divide kierują
na poszczególne funkcje.
Oczywiście może to dziwnie wygląda, że one są takie same, ale moglibyśmy tutaj napisać na przykład addFn,
no i wtedy tutaj mielibyśmy również to w ten sposób. Czyli tutaj tworzę nowy obiekt i mówię, że chcę,
aby miał on taką właściwość, a w tym przypadku będzie to metoda jak add i żeby ona kierowała na funkcję,
która została zwrócona z tego modułu.
Mam nadzieję, że jest to dla ciebie zrozumiałe. I teraz będziemy chcieli ten plik index.js zaimportować
w naszym pliku main.
Dlatego utworzę sobie zmienną, którą nazwiemy calc, i poleceniem require
będę chciał to zaimportować. I możesz się domyślać, że możemy wpisać coś takiego, bo jesteśmy w takiej strukturze
jak calculator i następnie index.js, albo po prostu w ten sposób. Ale nie musimy tego robić. Jeżeli ten
plik nazywa się index.js, to wystarczy, że podamy taką ścieżkę. Czyli wcześniej - już wiesz - działałoby to w
ten sposób, że Node próbowałoby znaleźć plik z rozszerzeniem calculator.js i dokładnie tak by było,
ale tego pliku tutaj nie ma, więc Node spróbuje znaleźć katalog. Katalog znalazło i w tym katalogu spróbuje
znaleźć plik index.js. Jeżeli taki plik tam się znajduje, to on zostanie wykonany.
No i jak widzisz, on po kolei wykona wszystkie inne pliki.
Przy okazji mielibyśmy tutaj błąd.
Wróćmy do takiej postaci.
To, co ten plik zwróci poprzez module.exports, zostanie nam przypisane w to miejsce do calc.
Czyli będzie to obiekt, który będzie zawierał właśnie takie właściwości jak add, subtract itd.
Teraz będziemy mogli z niego korzystać.
Więc spróbujmy sobie tutaj wpisać console.log i może jeszcze dopiszemy moduł główny, dlatego że wcześniej
we wszystkich modułach mieliśmy tego typu console logi, albo nawet napiszemy main.js.
Będzie to fajnie wyglądać w konsoli. I teraz spróbujemy skorzystać na przykład z calc i napiszemy tutaj add.
I znowu 5 i 6 będziemy chcieli sobie dodać. Zobaczmy, czy to zadziała.
Mamy tutaj plik main.js, a więc wpiszemy node main i dokładnie tak jest.
Tylko pojawił nam się jakiś błąd, a to oznacza, że popełniłem tutaj literówkę.
Wyczyszczę ekran, próbujemy raz jeszcze. Widzimy poszczególne console logi, na końcu nasz console.log moduł
main.js, no i wynik takiego dodawania.
W ten sposób możemy tworzyć moduły, które będą całkowicie w oddzielnym katalogu. I w nim jeden plik index.js
będzie nam to wszystko eksportował i dopiero to sobie zaimportujemy dalej.
Jak widzisz, w ten sposób w pliku main.js tak naprawdę w ogóle nie musimy wiedzieć, jak działa taki
moduł.
Możemy go od kogoś pobrać lub my go komuś udostępnimy.
Wiemy tylko, że zawiera on sobie cztery metody, z których warto korzystać.
A to, jak to zostało zaimplementowane tutaj,
tutaj mogłoby być bardzo wiele różnych funkcji pomocniczych czy lokalnych zmiennych,
nie musi nas wcale interesować. Teraz pokażę ci jeszcze jedną ciekawą rzecz. Otóż gdybyś nie chciał tego
pliku głównego w takim folderze nazywać index.js ale np. calculator, to możemy to zrobić. Zmienię sobie
teraz jego nazwę.
W ten oto sposób. No i tutaj musielibyśmy podać tę nazwę, ale możemy również zrobić to inaczej.
Otóż w tym katalogu stworzymy plik, który nazywa się package.json, a więc 03/calculator/package.json,
i w tym pliku package.json, który jeszcze w tym kursie później się pojawi, możemy napisać coś takiego
jak main i następnie tutaj nazwę pliku. Więc napiszemy calculator.js.
W ten oto sposób. I zobaczmy, czy to wszystko zadziała tak samo.
Okazuje się, że tak.
Czyli znowu, jak to działa?
Otóż Node w tym przypadku nie znajdzie pliku calculator.js, więc sprawdzi, czy mamy taki katalog.
Katalog się znalazł i teraz sprawdzi, czy jest w nim plik package.json.
Jeżeli tak, to sprawdzi, czy w tym pliku mamy klucz main i czy on kieruje na jakiś plik.
Jeżeli tak, to wykona ten plik jako plik główny.
Jeżeli nie, to będzie szukał pliku index.js.
W ten sposób to wygląda.
No i na koniec tej lekcji chcę ci pokazać jeszcze jedną ciekawą rzecz. Otóż oprócz importowanych katalogów, a także
plików z rozszerzeniem js możemy importować pliki json, które od razu zostaną sparsowane. I teraz
aby ci to pokazać, to w tym pliku calculator utworzę nowy plik json. Nazwiemy go config.json.
W ten sposób. I będę chciał w nim wpisać takie rzeczy.
Będzie to, powiedzmy, jakaś nazwa naszego modułu i jego wersja. Zapiszę to sobie. I teraz w pliku
może calculator.js gdzie sobie to wszystko eksportujemy, to napiszemy config i będę chciał tutaj wyeksportować
jeszcze jedną rzecz. Zaimportujemy ją sobie tutaj poleceniem require bezpośrednio, nie musimy tego robić
wcześniej, możemy to tutaj wpisać bezpośrednio. I będę chciał z tego katalogu zaimportować sobie config.
Zauważ, że znowu nie podaję tutaj json, chociaż mógłbym, ale domyślnie Node najpierw będzie sprawdzać, czy jest
to rozszerzenie js, czy taki plik istnieje, później będzie szukać json oraz folderów.
Więc w ten sposób plik config.json zostanie nam wczytany pod ten oto klucz config.
Ale nie tylko zostanie wczytany, ale także sparsowany i będzie dostępny jako obiekt JavaScript, czyli normalnie
do tego name czy version
po kropce będzie się można odwoływać.
Zauważ, że w kalkulatorze sobie to eksportujemy, a to oznacza, że tutaj będzie to dla nas dostępne. Dlatego mogę
zrobić console.log i napiszemy sobie coś takiego.
Tutaj odwołamy się do calc.config i ten config już jest sparsowany.
Czyli mamy coś takiego jak name.
I do tego będę chciał sobie jeszcze dodać wersję. I przejdźmy do terminala, zobaczmy, czy to wszystko
zadziała poprawnie.
No i jak widzisz, dokładnie tak też się dzieje.
Czyli z tego zapamiętaj sobie, że oprócz tego, iż możemy importować pojedyncze pliki JavaScript, możemy
importować jakby całe foldery, gdzie będzie szukany plik index.js albo plik, który jest wskazany w package.json
jako main, to możemy również importować sobie za pomocą require pliki json, które od razu będą parsowane
na obiekty JavaScript, z których będzie można później normalnie korzystać.