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 krótko, jak możesz nasłuchiwać na zmiany w plikach lub katalogach.
Jest to rzecz, która może być przydatna i jest wykorzystywana np. przez takie narzędzie jak Grant czy
Gulp,
O nich jeszcze powiemy pod koniec tego kursu, być może już wcześniej o nich słyszałeś.
Możesz znaleźć w dokumentacji Node kilka metod.
Najważniejszą, z której będziemy korzystać, jest fs.watch.
Mamy jeszcze metodę watch file i unwatch file, ale nawet twórcy Node tutaj w dokumentacji zachęcają, by z nich nie korzystać,
a by korzystać z tej metody fs.watch.
Dlatego my z niej będziemy chcieli skorzystać i będę chciał nasłuchiwać na zmiany w pliku
Lorem1.txt, który znajduje się w katalogu files.
Metoda wygląda w ten sposób: fs.watch, podajemy ścieżkę, więc naszą funkcją pomocniczą
będę chciał taką ścieżkę tutaj zwrócić i następnie podajemy sobie funkcję. I ta funkcja wykona się za
każdym razem, kiedy będą jakieś zmiany na tym pliku.
Zmiana to może być np. zmiana nazwy takiego pliku lub zmiana jego treści.
Dlatego ta funkcja przyjmuje dwa parametry.
Pierwszy z nich jest to eventType - dowolnie go możesz nazwać - i on tutaj będzie miał wartość rename lub
change, czyli właśnie czy zawartość pliku została zmieniona, czy tylko nazwa tego pliku.
A jako drugi parametr będziemy mieli filename, czyli samą nazwę tego pliku lub katalogu. Bo to jest ważne,
że możemy nasłuchiwać również na zmiany w katalogach.
No i tutaj mógłbym zrobić console.log, w którym wpiszemy sobie cokolwiek
za każdym razem, gdy ten plik się zmieni, ale nie chcę na to tracić czasu. Od razu stworzymy sobie tutaj
fajny, praktyczny przykład.
Chciałbym za każdym razem, gdy coś się zmieni w tym pliku lorem1.txt wziąć całą tą treść i
zamienić ją na wielkie litery i zapisać w nowym pliku. Więc zrobimy sobie to w ten sposób, że ta funkcja, mówiłem
ci, wykona się za każdym razem, gdy coś się w tym pliku zmieni.
I właśnie wtedy będziemy chcieli cały ten plik odczytać.
Wiesz już, jak to robić za pomocą metody readFile.
Tutaj z funkcji pomocniczej file, którą mamy u góry, skorzystam. Mogę podać lorem1.txt, ale równie
dobrze mogę podać filename.
Bo skoro mamy to tutaj pod zmienną wrzucone do tej funkcji, to możemy sobie to przekazać dalej, będziemy mieli
poprawną ścieżkę.
Chcę tutaj zaznaczyć, że ten plik odczytujemy nie jako buffer, ale jako tekst zdekodowany w UTF-8 i następnie będziemy
mieli funkcję. Ta funkcja przyjmuje błąd i dane.
To wszystko już znasz.
Jeżeli nie będzie błędu, czyli if not error - w ten sposób sobie to zrobimy - to chcę całe te dane odczytane z
tego pliku, czyli w zasadzie data,
tak to powinno się nazwać, zamienić na wielkie litery i zapisać w nowym pliku.
Dlatego skorzystamy z fs.writeFile, również już tę metodę ci pokazywałem.
Będę chciał plik nazwać
lorem1uppercase.txt.
Będzie on w katalogu files. Tutaj jako drugi parametr podajemy, co chcemy tam wpisać, a więc data to
będzie w naszym przypadku string, nie buffer tylko string, bo podałem UTF-8. Stringi w JavaScript mają metodę
toUpperCase i to będziemy chcieli zapisać. Jako trzeci parametr pamiętaj, że podajemy funkcję callback, która
się wykona, jeśli się uda, lub nie.
W tym przypadku już jej nie będę podawał.
Moglibyśmy oczywiście to zrobić i obsłużyć ewentualny błąd, ale na nasz przykład tyle wystarczy.
Czyli teraz kiedy wykonamy sobie ten moduł czy cały w zasadzie ten plik, to będziemy nasłuchiwać na zmiany w
pliku lorem1.txt.
Zauważ, że tutaj lorem1uppercase nie istnieje. Wykonajmy sobie node index. Ok.
I to, co jest ważne, zauważ, że proces się nie kończy tak, jak było do tej pory. Widać to tutaj po tym kursorze,
który nie wyskoczył. Nie mamy nowej strzałki. To oznacza, że ten proces jakby "wisi". Aby go zakończyć, wciskamy
Ctrl+C.
Natomiast ja nie chcę go kończyć i on się nie zakończył z prostego powodu. Otóż nasłuchuje na zmiany w
pliku. Czyli teraz jeżeli sobie dowolną rzecz zmienię w tym pliku, nawet jeżeli go tylko zapiszę, to zauważ,
że został utworzony nowy plik lorem1uppercase i wszystko w nim jest zamienione na wielkie litery,
czyli watch, jak widać, działa. Jeżeli cokolwiek sobie tutaj będę dopisywał teraz - może podzielę ten ekran w
ogóle na dwie połowy, przejdę do View > Layout i tutaj sobie wybierzemy Columns 2, przesunę to tutaj - powinno nam
się to odświeżać, zaraz zobaczymy.
Jeżeli tutaj cokolwiek zmienię, czyli dodam nową linijkę,
jeżeli to zapiszę, to powinno się to zmienić w tym pliku. Jak widzisz, automatycznie tak się stało.
Czyli w tym momencie stworzyliśmy sobie taki prosty moduł, który pozwala nam wpisywać dane do jednego
pliku, możemy je przekonwertować i zapisać do innego pliku.
W ten sposób mniej więcej działają np. preprocesory,
gdybyśmy chcieli nasłuchiwać na pliku SAS, kompilować go do pliku CSS i tak dalej. Jest to tylko uproszczony
przykład, który wymagałby jeszcze trochę pracy, aby obsłużyć wszystkie błędy itd.
Ale widzisz, że on działa. W ten sposób nasz watcher nasłuchuje na zmiany w tym pliku i za każdym razem
kiedy one nastąpią, wywołuje odpowiednią funkcję.