Dawid Panfil

Widoki w Node.js

Jest to drugi wpis z cyklu Node.js. Dzisiaj skupimy się na widokach.

Jeśli nie czytałeś pierwszej części to zapraszam to artykułu:: „Node.js pierwsze starcie„. Napisałem tam czym jest Node.js, wyjaśniłem podstawowe definicje z nim związane oraz jaki projekt napiszemy, także lektura powyższego wpisu jest obowiązkowa.

Czym jest wzorzec MVC?

Jeśli doczytałeś czym jest MVC, to bardzo dobrze. Jeśli nie to musisz zadowolić się wyjaśnieniem, że jest to wzorzec – sposób pisania aplikacji, który oddziela widok od abstrakcji – czyli unika robienia tak zwanego spaghetti code. Zasada jest prosta. Oddzielamy widoki od logiki aplikacji, a kontroler to wszystko obsługuje. Wyjaśnienie literek:

  • M jak model – tutaj są wszystkie obiekty potrzebne do obsługi logiki biznesowej
  • V jak view – widoki, warstwa prezentacyjna. Wyświetlanie danych z przekazanych z modelu. Inaczej mówiąc – to co widzi użytkownik.
  • C jak controller – odpowiada za komunikacje między modelem a widokiem. Do tego dochodzi jeszcze router, który odpowiada za uruchomienie odpowiedniego kontrolera. Jego najprostszą wersję pokazałem w pierwszym wpisie.

Po pierwsze controller

Nasz plik index.ts zaczyna puchnąć i jest ogólnie nieczytelny, dlatego najpierw wprowadzimy sobie małe modyfikacje naszej aplikacji. Wydzielimy sobie funkcje do osobnych plików.

Stwórz w projekcie w folderze src folder controllers. Ogólnie wszystkie foldery i pliki jakie będziemy tworzyć muszą się znajdować w folderze src. No chyba, że:

  • napiszę, że ma być poza tym katalogiem
  • są to pliki konfiguracyjne typu package.json
  • lub ustawisz inną ścieżkę plików

Zaczynamy poprawki

Jednak na ten moment to nie polecam grzebać w ustawieniach, tylko postępować zgodnie z instrukcjami (a grzebać w projekcie obok ;)). Będzie mniejsze ryzyko powstania błędu.

Teraz stwórz sobie plik homeController.ts w tym folderze z taką zawartością:

import {Request, Response} from 'express';

console.log('zaimportowalo');
export let index = (req: Request, res: Response) => {
    console.log('jestem w index');
    res.send('hello');
    return;
};

I o co w tym wszystkim chodzi? Jak wspominałem najpierw importujemy, to co używamy. To jest jasne. console.log() czym jest wiesz, ale dlaczego w tym miejscu zaraz zobaczysz. Następnie mamy funkcję index i słówko export przy nim. Informujemy nim, że funkcja w zmiennej index ma być publiczna – czyli dostępna wszędzie gdzie być powinna dostępna ;). Nie jest to oczywiście dokładne wyjaśnienie tego słowa export, ale na nasze potrzeby w tym momencie to wystarczy. No i mamy zwykłą funkcję taką jak mieliśmy w pliku index.ts – czyli nie trzeba nic tłumaczyć. Przejdź zatem do tego pliku i nanieś odpowiednie poprawki.

Po pierwsze dodaj import:

 import * as homeController from './controllers/homeController'; 

Tutaj mamy taki mały myk, że importujemy wszystko (*) pod nazwą homeController dzięki temu możemy się odwoływać do funkcji tam zawartych jak do metod w klasie. Także przerabiamy ścieżkę „/” tak, aby wywołała naszą funkcję index w naszym pliku homeController.

app.get('/', homeController.index);

Tak samo jak w osobnej funkcji (patrz na aboutMe) nie musimy podawać parametrów. Same się uzupełnią (dla ciekawskich nazywa się to Dependency Injection) . No to teraz możesz sobie odpalić aplikacje i sprawdzić czy działa. Przy okazji obserwuj konsole. Dostaniesz słówko zaimportowało i następnie, że nasza przykładowa aplikacja działa na porcie 3000. Uruchom przeglądarkę. Pojawi się kolejny log: Jestem w index.

No to teraz przerób sobie resztę ścieżek na takie controllery. Tylko uprzedzam – nie jest to finalna wersja. TypeScript jest obiektowy, także nie będziemy pisać proceduralnie. Zrobiliśmy to tylko po to, aby było czytelniej na ten moment i do niego jeszcze wrócimy do tego tematu.

Jednak resztę ścieżek usuń lub popraw w następujący sposób.

V jak View – wybieramy system templatek

Template – czyli szablony. Możemy po prostu odczytać plik „X” z folderu views i wypluć go przez funkcję res.body(), tylko wyobraź sobie jak to będzie wyglądać – gdy powstanie 30 szablonów i do tego w każdym trzeba wyświetlić zmienne, a nie daj boże jeszcze niech pojawią się instrukcje warunkowe – rzeź niewiniątek.

Dlatego powstały silniki do renderowania widoków. Takie jak Pug, Mustache, Handlebars, czy EJS. O tym możesz sobie poczytać w dokumentacji express.js bo bardzo ładnie to opisali. Domyślny jest Pug, no ale mi się nie podoba także wykorzystamy sobie Handlebars, najbardziej mi przypomina Twig’a z Symfony.

Konfigurujemy Handlebars w Node.js

Najpierw trzeba zainstalować moduł, jak wiesz z poprzedniego wpisu trzeba wykorzystać npm:

 npm install express-handlebars --save

Zainstalowało, to wracamy do naszego pliku index.ts i importujemy plik:

import handlebarsExpress from  'express-handlebars'; 

Następnie po stworzeniu app doklejamy:

const hbs = handlebarsExpress.create(
    {extname: '.html'}
);

app.engine('.html', hbs.engine);
app.set('view engine', '.html');
app.set('views', __dirname + '/views');

Najpierw tworzymy sobie obiekt hbs z wstępną konfiguracją naszego systemu templatek. Następne dwie linijki informują jaki silnik będzie obsługiwać nasze widoki i w jakim mają być one folderze. Natomiast ostatnia gdzie one się znajdują. __dirname wskazuje natomiast aktualny folder.

W handlebars jest coś takiego jak layouts na ten moment tym się nie przejmuj. Utwórz sobie folder views/layouts i w nim plik main.html, w którym będziesz mial taki kod:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{{body}}}
</body>
</html>

Zwróć uwagę na zapis: {{{body}}}. Jest to jeden ze sposobów na wyświetlanie zmiennych. Przejdź do naszego homeController i podmień linijkę z odpowiedzią na:

render('index');

I stwórz sobie plik index.html w folderze views. Jako zawartość daj nagłówek z napisem Dzień dobry. Odpal znowu aplikację (npm run serve) i otwórz przeglądarkę. Dostaniesz nasz szablon. No i działa dostaliśmy wartość Dzień dobry.

Warto wspomnieć, że w dokumentacji na npmjs podają rozszerzenie .hbs dla plików z widokami. Ja użyłem tutaj html, ponieważ IDE koloruje mi ładnie kod, a nie znalazłem działającego pluginu dla Handlebars.

Na dziś to już koniec zabawy z Node.js

Przynajmniej z mojej strony. Twoim zdaniem domowym jest poznać jak:

  • przekazać zmienne do widoku
  • przerobić wszystkie widoki
  • zapoznać się z Handlebars.

Ja natomiast w między czasie wstawię szybki krótki wpis o używaniu tego Handlebars (zmienne, pętle czy instrukcje warunkowe). Także do zobaczenia.

Wszystko to co pokazałem, staram się pokazywać w najprostszy sposób – nie zawsze zgodny z ogólnymi praktykami. Także pamiętaj, aby uzupełniać wiedzę, którą Ci przekazuje w moich artykułach. Jeśli będziesz miał z czymś problem to zachęcam do komentowania.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *