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żesz tworzyć katalogi, a także pliki, i jak do tych plików zapisywać
informacje.
Mamy tutaj bazę z lekcji poprzednich już i od tego będziemy chcieli zacząć.
Na początek pierwsza z metod, którą ci pokażę, służy do tworzenia katalogów i nazywa się ona mkdir.
Jeżeli kiedykolwiek w terminalu, np. na Macu lub na Linux, korzystałeś z takiej metody, to będziesz wiedział,
o co chodzi. Jesteśmy w przykładzie 13.
Jeżeli wpiszę ls, zauważ, że mamy tutaj tylko plik index.js.
Natomiast w terminalu mamy takie polecenie jak mkdir i mogę napisać np. files i w ten sposób utworzę
sobie taki katalog. Natomiast my będziemy chcieli to zrobić z poziomu Node.js.
Dlatego teraz za pomocą rmdir usunę ten katalog i potwierdzimy poprzez ls, że on rzeczywiście zniknął.
Nie wiem, czy pamiętasz, ale na początku tego kursu, kiedy mówiłem o tym, czym jest Node.js, pokazałam ci fragment
prezentacji oryginalnej Node.js, gdzie jej autor mówił m.in. o tym, że tworząc Node, starał się metody
szczególnie do pracy z systemem plików nazywać tak, jak są one nazwane w tych systemach UNIX po
to, aby były one dla nas znane.
Dokładnie to miał na myśli, tworząc metodę mkdir.
Czyli skoro znamy ją np. z Linux czy tutaj terminala na Macu, to również w Node.js możemy ją znaleźć na module
file system.
Odwołamy się zatem do mkdir - w ten sposób. I jako pierwszy parametr musimy podać oczywiście ścieżkę do
katalogu, który chcemy utworzyć.
Tym razem nie skorzystamy z funkcji file, którą mamy powyżej, bo ona, jak wiesz, zwracała nam odwołanie
do pliku.
Dlatego tutaj skorzystam po prostu z path.join. W ten sposób. Napiszemy dirname, aby odwołać się do katalogu, w
którym jesteśmy.
Następnie nazwa katalogu, który chciałbym utworzyć. Jest to files.
W ten sposób będziemy taki katalog mogli utworzyć. I funkcja callback, tym razem znowu error-first.
To znaczy, że mamy tutaj jako pierwszy parametr błąd.
W tym przypadku jest to jedyny parametr, bo jeżeli uda się utworzyć taki katalog, to będziemy tutaj mieli
wartość null.
Jeżeli nie, to będzie tutaj obiekt błędu.
Z tego powodu możemy sobie to obsłużyć taką instrukcją.
Jeżeli z jakiegoś powodu nie uda się utworzyć katalogu, a powody mogą być różne - on może po pierwsze już
istnieć albo np. chcemy utworzyć katalog w jakimś innym katalogu, do którego nie mamy odpowiednich pozwoleń
jako użytkownik wykonujący proces Node - to będziemy mieli błąd i będę chciał wyświetlić console.log z jego
powodem, a także zakończyć tę funkcję.
Natomiast jeżeli się uda, to przejdziemy poniżej i zobaczymy odpowiedni console.log.
Raz jeszcze upewnijmy się, że tutaj nic nie ma. Mam tylko plik index, dlatego teraz go wywołamy.
Ok. Katalog został utworzony i teraz za pomocą ls możemy sprawdzić, że katalog files faktycznie się pojawił.
I tutaj również w moim edytorze widzimy, że katalog tutaj jest.
Spróbujmy raz jeszcze wykonać cały ten program poleceniem node.
I zauważ, że tym razem błąd się pojawił.
Mamy "Nie udało się utworzyć katalogu", a powód jest to "file already exists".
To oznacza, że nie mogliśmy utworzyć takiego katalogu, bo on już istnieje i w tym przypadku został zwrócony
błąd.
Do błędów warto jednak zaglądać.
A oznacza to tylko tyle, że jeżeli zrobimy console.log(err), to będziemy mogli zobaczyć jeszcze pewne
informacje o tym błędzie.
Przede wszystkim ten błąd ma taką właściwość jak code i code jest to EEXIST, czyli mamy coś takiego.
I ten kod oznacza to, co widzieliśmy poprzez właściwość message, czyli że już taki katalog istnieje.
Błędy mogą być różne, ale ten zawsze będzie taki sam.
Więc jeżeli chcielibyśmy sobie obsłużyć jeszcze jeden tutaj wyjątek, mianowicie wtedy, kiedy katalog istnieje, to wywołać
inny console.log, to możemy to zrobić w taki sposób:
if(err), następnie code i porównamy, czy on równa się tej właśnie treści, to wtedy będę chciał sobie wyświetlić
console.log, że katalog już istnieje
i będę chciał zakończyć. Natomiast w innym wypadku powiedzmy, że chcemy tutaj zrobić
throw err.
W ten sposób. Czyli jeżeli będziemy mieli inny powód, a nie taki, że katalog już istnieje, to wyrzucimy sobie ten
błąd i proces również automatycznie się zakończy.
W ten sposób zaglądając sobie do błędów,
możesz obsłużyć różne przypadki. I teraz wywołajmy sobie raz jeszcze ten program. I widzimy po prostu console.log
"Katalog już istnieje" i nic złego tutaj więcej się nie stało, dlatego że ten przypadek został w tym momencie
obsłużony. Ok.
Wiemy już, jak utworzyć katalog i to zrobiliśmy, więc mamy katalog files, a teraz do niego będę chciał
utworzyć sobie kilka plików.
Dlatego przejdziemy sobie poniżej. Zrobię trochę miejsca i tutaj skorzystamy z kolejnej metody modułu
file system, która nazywa się writeFile i pozwala nam zapisywać do pliku lub tworzyć nowe pliki, a więc
fs.writeFile - będę chciał utworzyć plik lorem1.txt, więc skorzystamy z metody, którą mamy tutaj, pomocniczej, która
nam ścieżkę odpowiednią zwróci.
I tutaj jako drugi parametr podajemy treść, którą chcemy wpisać do takiego pliku.
Ja chcę tylko ten plik utworzyć. Chcę, aby był on pusty.
Dlatego podam sobie pusty ciąg znaków i jako ostatni parametr podajemy tutaj funkcję, która znowu przyjmie
error,
jeżeli on wystąpi. Jeżeli nie, to będzie tutaj wartość null.
Więc jeżeli uda się utworzyć taki plik i do niego dane zapisać, to będziemy mogli sobie tę funkcję wywołać.
Jeżeli się nie uda, ona również się wywoła.
Dlatego obsłużmy sobie to w ten sposób.
Znowu - jeżeli będzie jakiś błąd, to chcę wyświetlić odpowiedni console.log z powodem i zakończyć.
Przejdźmy sobie tutaj.
Upewnijmy się, że nic tutaj nie ma. Ja skorzystam u siebie z polecenia tree, które wyświetli mi, co znajduje się
w katalogu files. Jak widzimy - nic.
Więc teraz wywołajmy sobie node index. Widzimy, plik
lorem1.txt został utworzony. Więc teraz jeżeli zrobię tree na katalogu files, to zobaczymy, że w środku rzeczywiście
znajduje się plik lorem1.txt.
Tutaj oczywiście też możemy to potwierdzić.
Jest to plik pusty.
Przejdźmy na sekundę do dokumentacji file system i znajdziemy metodę writeFile. Ona znajduje się w tym
miejscu. I wyszukałem ją, bo chcę ci pokazać, że możemy jeszcze tutaj podać jako trzeci parametr kodowanie.
Domyślnie jest to UTF-8.
Jeżeli skorzystamy tutaj ze stringu jako drugi, natomiast możemy je tutaj podać, a jako ostatni dopiero callback.
Ja nie podałem, więc domyślnie będzie ten plik zapisany również w kodowaniu UTF-8. A zatem teraz spróbujmy sobie
coś do tego pliku zapisać.
Mogliśmy to zrobić od razu, podając tę treść w tym miejscu, natomiast ja będę chciał ci pokazać kolejną
metodę, która nazywa się appendFile, i pozwala nam zapisywać treść na koniec danego pliku.
I teraz z niej skorzystamy. Ja ją od razu tutaj wkleję.
Tak to będzie wyglądać.
Jak widzisz, w zasadzie wszystkie te metody wyglądają bardzo podobnie.
Czyli w appendFile, tak samo jak writeFile, podajemy ścieżkę, następnie co chcemy zapisać i następnie
funkcję zwrotną.
I tutaj co ja chcę zapisać w tym pliku?
Otóż aktualną datę chcę sobie pobrać. Date.now zwróci nam datę w milisekundach od 01 stycznia 1970 roku,
czyli tzw. epoch time.
I będę chciał ją sobie tam wpisać i na końcu dodać znak nowego wiersza - w ten sposób.
I znowu mamy tutaj standardowy błąd czy obsługę tego błędu.
Zobaczmy, jak to będzie wyglądać.
Plik lorem1.txt jest pusty. On wcześniej został utworzony.
Jeżeli jakiś błąd nam się pojawi przy jego tworzeniu tutaj, to będzie on wyświetlony.
Natomiast jeszcze ważna informacja jest taka, że w tym miejscu tworzymy plik lorem1.txt.
Jeżeli on już istnieje, to zostanie po prostu nadpisany.
Czyli tutaj po wywołaniu node index nie powinniśmy mieć błędów.
Zobaczmy. Widzimy - plik został utworzony i tutaj mamy dodaną treść do pliku lorem1.txt. Zerknijmy.
I rzeczywiście taki czas został dodany, a także znak nowego wiersza, co widzimy w tym miejscu.
Jeżeli raz jeszcze wykonam sobie tę instrukcję, to powinniśmy tutaj mieć kolejną datę dodaną na końcu. Jak
jednak widzisz, nie została ona dodana na końcu.
Ale to wyłącznie z tego powodu, że ten plik już wcześniej istniał i został nadpisany taką instrukcją.
Czyli jeżeli to byśmy sobie teraz usunęli albo tutaj sprawdzili poprzez exists, czy taki plik istnieje, to
wyglądałoby to już inaczej. Czyli teraz zostało to poprawnie dodane i każde kolejne wywołanie będzie
do tego pliku dopisywać taką informację, bo nie jest on już od nowa tworzony za pomocą tej instrukcji.
Gdybyś nie pracował na plikach tekstowych ale na jakichś bardziej zaawansowanych plikach, np. plikach
audio, to również możesz je w ten sposób zapisywać. Jako drugi parametr
po prostu nie przekażesz stringu ale buffer i będziesz mógł za pomocą buffera wpisywać kolejne bity informacji
do pliku.
Przedostatnią metodą, którą chcę ci pokazać, jest metoda createWriteStream, którą już w tym kursie widziałeś.
Ja wykomentuję to, co mieliśmy do tej pory, aby w konsoli mieć czysto.
Czyli to się już nie będzie wykonywać.
Natomiast teraz utworzymy sobie nowy zapisywalny stream. W ten sposób. W lekcji o streamach pokazywałem ci,
jak to działa. Więc będziemy chcieli, aby plik lorem2.txt się tutaj pojawił i aby był on streamem zapisywalnym.
Teraz będę chciał do niego zapisywać. Do streamów możemy zapisywać za pomocą metody write
jakieś pojedyncze informacje czy w zasadzie wielokrotnie możemy z niej korzystać.
Natomiast jeżeli chcemy zamknąć taki stream, to korzystamy z metody end i to, co jest ważne, to metoda end również
może tutaj przyjąć ostatnią porcję informacji.
Czyli gdybym chciał tylko raz do tego pliku coś zapisać, to mogę napisać lorem.end i tutaj wpisać jakieś
informacje, np. lorem impsum.
W ten sposób. Wykonajmy to sobie i zobaczmy, czy rzeczywiście to zadziała.
Nic się nie wydarzyło złego, więc widzimy, że to działa.
Natomiast nie ma sensu tworzenie takiego streamu, jeżeli tylko raz będziemy chcieli do niego coś zapisać.
Dlatego będziemy chcieli tutaj skorzystać z innej metody, mianowicie z pipe, którą już znamy. I pokażę ci, w jaki
sposób możemy plik lorem1.txt skopiować do pliku lorem2.txt.
Jak to będzie wyglądać?
Mamy tutaj trochę informacji, więc teraz sobie je przekopiujemy. Zrobimy to za pomocą pipe, które również już znasz z
lekcji o streamach, ale zanim to zrobimy, to będę chciał przypisać zdarzenie do tego streamu na zakończenie.
W ten sposób to będzie wyglądać.
Pamiętasz na pewno, że streamy dziedziczą z EventEmittera,
dlatego możemy przypisywać zdarzenia.
Jednym z nich jest finish, czyli kiedy zakończymy wczytywanie takiego pliku czy zapisywanie do takiego
pliku, to ta funkcja się wykona. I teraz jedną linijką możemy tak naprawdę skopiować zawartość jednego
pliku do drugiego. Musimy sobie tylko utworzyć stream odczytywalny, czyli read stream, z tego pliku lorem1.txt.
Zrobimy to w ten sposób. Do zmiennej lorem1 tutaj zostanie zwrócony oczywiście stream odczytywalny
z tego pliku i teraz za pomocą pipe będziemy całą zawartość kopiowali do pliku lorem2.
Zatem lorem1.pipe(lorem2).
O tym mówiłem, mając na myśli jedną linijkę, czyli ta jedna linijka skopiuje nam cały ten plik, a kiedy
to się zakończy, wykona nam się console.log.
Sprawdźmy.
Widzimy zakończone kopiowanie treści pliku i teraz w lorem2 powinniśmy mieć dokładnie taką samą zawartość
jak w lorem1.
Tak to wygląda i możesz w ten sposób kopiować nawet duże pliki, bo wiesz, że streamy będą po kawałku wczytywać
tylko informacje do pamięci i kopiować je później do kolejnego pliku.
Dlatego będzie to wszystko dosyć wydajne.
Na koniec szybko jeszcze jedna metoda, która pozwoli ci utworzyć katalog tymczasowy, gdybyś np. na serwerze
pracował z uploadem jakichś plików i chciałbyś mieć foldery tymczasowe, to możemy skorzystać z takiej
metody. Wykomentuję to, co mieliśmy tutaj, i ostatnią metodę wkleję w tym miejscu.
Ta metoda nazywa się mkdtemp.
I działa w ten sposób, że podajemy tutaj ścieżkę do katalogu, jaki chcemy utworzyć, z jego przedrostkiem.
Czyli tutaj, gdzie jesteśmy, chcę utworzyć katalog uploads + pauza i to, co tutaj zostanie dodane, to właśnie
jest już generowane w sposób losowy przez tę metodę, czyli taki katalog chcę tymczasowy utworzyć.
Tutaj mamy znowu funkcję error-first callback.
Jeżeli był błąd, to pod pierwszym parametrem się znajdzie, a pod drugim będziemy mieli nazwę nowo utworzonego
katalogu, dlatego możemy to w ten sposób wyświetlić.
Możemy tutaj zakończyć poprzez return, nie wyrzucając tego błędu.
Zobaczmy, jak to będzie wyglądać.
Utworzono katalog tymczasowy. Widzimy całą jego ścieżkę i jego nazwę, czyli uploads+pauza - to, co
podałem. I tutaj losowe już znaki.
Ten katalog pojawił się w tym miejscu i możemy do niego teraz powiedzmy coś zuploadować.
Natomiast mamy również wersję synchroniczną, tak jak ci mówiłem.
Wiele z tych metod, które tutaj się znajdują, posiada swoje synchroniczne wersje, dlatego gdybyś chciał taki
katalog utworzyć tymczasowo i od razu mieć referencje do niego w zmiennej, to możemy to zrobić w taki
sposób.
Jak widzisz, metoda wygląda identycznie, ale mamy tutaj jeszcze dopisek sync.
I nie ma tutaj funkcji callback, dlatego że to wszystko musi się wykonać i w tym miejscu zostać zwrócone,
a dopiero później będziemy mieli console.log.
Znowu pamiętaj, że jeżeli pojawi się błąd, to cały ten blok musisz zawrzeć jeszcze w bloku try catch.
Zobaczmy, jak to będzie wyglądać.
Utworzono katalog tymczasowy.
Jak widzisz, tym razem ma on inną nazwę. Faktycznie pojawił on się tutaj.
Podsumowując tę lekcję, zobaczyłeś, w jaki sposób możemy tworzyć nowe pliki i katalogi za pomocą mkdir
czy writeFile.
Także zobaczyłeś metodę appendFile, która pozwala dopisywać do końca pliku jakieś nowe informacje i przypomniałeś
sobie również, w jaki sposób działają streamy i jak łatwo za pomocą jednej linijki jest skopiować jeden
plik do drugiego pliku, korzystając z pipe.
Na koniec pokazałem ci jeszcze taką metodę, która być może kiedyś ci się przyda do tworzenia tymczasowych
katalogów.