diff options
Diffstat (limited to 'files/pl/learn/server-side/express_nodejs/skeleton_website/index.html')
| -rw-r--r-- | files/pl/learn/server-side/express_nodejs/skeleton_website/index.html | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/files/pl/learn/server-side/express_nodejs/skeleton_website/index.html b/files/pl/learn/server-side/express_nodejs/skeleton_website/index.html new file mode 100644 index 0000000000..d3a949c8cd --- /dev/null +++ b/files/pl/learn/server-side/express_nodejs/skeleton_website/index.html @@ -0,0 +1,528 @@ +--- +title: 'Szkolenie z Express - część 2: Tworzenie szkieletu aplikacji webowej' +slug: Learn/Server-side/Express_Nodejs/skeleton_website +tags: + - Express + - Początkujący + - Szkolenie + - Wprowadzenie + - środowisko programisty +translation_of: Learn/Server-side/Express_Nodejs/skeleton_website +--- +<div>{{LearnSidebar}}</div> + +<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs")}}</p> + +<p class="summary">W drugim artykule cyklu <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Szkolenie z Express</a> zbudujemy "szkielet" aplikacji webowej, którą będziemy później rozbudowywać o kolejne elementy: ścieżki, szablony/widoki i odwołania do bazy danych. </p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Wymagania:</th> + <td>Przeczytanie artykułu <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Set up a Node development environment</a>.</td> + </tr> + <tr> + <th scope="row">Cele:</th> + <td>Umiejętność samodzielnego utworzenia własnego projektu aplikacji webowej za pomocą <em>Express Application Generator</em>.</td> + </tr> + </tbody> +</table> + +<h2 id="Wstęp">Wstęp</h2> + +<p>Artykuł przedstawia tworzenie szkieletu aplikacji webowej Biblioteka przy pomocy narzędzia <a href="https://expressjs.com/en/starter/generator.html">Express Application Generator</a>. W kolejnych artukułach będziemy ją rozbudowywać o kolejne elementy. Proces tworzenia jest bardzo prosty i wymaga wywołania tylko jednego polecenia z nazwą budowanej aplikacji. Opcjonalnie można także podać silnik do renderowania widoków i generator CSS.</p> + +<p>W kolejnych sekcjach przyjrzymy się bliżej działaniu generatora, poznamy opcje widoków/CSS. Zostanie też wyjaścniona struktura utworzonej aplikacji. Na zakończenie poznasz metody uruchomienia utworzonej aplikacji oraz zweryfikowania jej działania. </p> + +<div class="note"> +<p><span style="line-height: 1.5;"><strong>Uwaga</strong>: <em>Express Application Generator</em> nie jest jedynym narzędziem do tworzenia aplikacji Express, a struktura utworzonych projektów nie jest jedyną właściwą. Wygenerowana aplikacji posiada modularną strukturę, która może być łatwo rozszerzana oraz jest wystarczająco przejrzysta i zrozumiała. Informacje o tym jak zrobić minimalną aplikację Express znajdziesz w <a href="https://expressjs.com/en/starter/hello-world.html">Hello world example</a> (dokumentacja Express).</span></p> +</div> + +<div class="note"> +<p><span style="line-height: 1.5;"><strong>Uwaga</strong>: W tym szkoleniu wykorzystano wersję Express zdefiniowaną w pliku <strong>package.json</strong> utworzonym automatycznie przez <em>Express Application Generator.</em> I niekoniecznie jest to najnowsza wersja! </span></p> +</div> + +<h2 id="Korzystanie_z_generatora_aplikacji">Korzystanie z generatora aplikacji</h2> + +<p>Powinieneś mieć zainstalowany generator jako część środowiska przygotowanego w artykule <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Przygotowanie środowiska programisty Node</a>. W ramach przypomnienia instalacja generatora aplikacji Express wymaga wpisania poniższego polecenia:</p> + +<pre class="brush: bash notranslate"><code>npm install express-generator -g</code></pre> + +<p>Generator posiada wiele opcji, które możesz poznać za pomocą polecenia <code>--help</code> (lub <code>-h</code>):</p> + +<pre class="brush: bash notranslate">> express --help + + Usage: express [options] [dir] + + + Options: + + --version output the version number + -e, --ejs add ejs engine support + --pug add pug engine support + --hbs add handlebars engine support + -H, --hogan add hogan.js engine support + -v, --view <engine> add view <engine> support (dust|ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) + --no-view use static html instead of view engine + -c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css) + --git add .gitignore + -f, --force force on non-empty directory + -h, --help output usage information +</pre> + +<p>Wpisując wyłącznie polecenie <code>express</code> utworzysz projekt w bieżącym katalogu z domyślnym silnikiem zablonów Jade i czystym CSS. Dodanie nazwy katalogu spowoduje utworzenie projektu w tym właśnie katalogu. </p> + +<pre class="brush: bash notranslate"><code>express</code></pre> + +<p>Opcją <code>--view</code> możesz wyspecyfikować inny generator widoków a <code>--css</code> podać preprocesor CSS.</p> + +<div class="note"> +<p><strong>Uwaga:</strong> Pozostałe opcje wyboru silnika szablonów(n.p. <code>--hogan</code>, <code>--ejs</code>, <code>--hbs</code> itd.) są już przestarzałe i nie należy z nich korzystać . Skorzystaj z opcji <code>--view</code> (or<code> -v</code>)!</p> +</div> + +<h3 id="Jaki_silnik_szablonów_wykorzystać">Jaki silnik szablonów wykorzystać?</h3> + +<p>Paczka <em>Express Application Generator</em> pozwala na skonfigurowanie wielu popularnych silników renderujących, w tym <a href="https://www.npmjs.com/package/ejs">EJS</a>, <a href="http://github.com/donpark/hbs">Hbs</a>, <a href="https://pugjs.org/api/getting-started.html">Pug</a> (Jade), <a href="https://www.npmjs.com/package/twig">Twig</a> i <a href="https://www.npmjs.com/package/vash">Vash</a>, spośród których to Jade jest domyślnie instalowany w sytuacji braku specyfikacji silnika. Sam Express wspiera znaczną liczbę innych języków szablonów <a href="https://github.com/expressjs/express/wiki#template-engines">out of the box</a>.</p> + +<div class="note"> +<p><strong>Uwaga:</strong> Jeśli chcesz skorzystać z silnika, który nie jest wspierany przez generator to zapoznaj się publikacją <a href="https://expressjs.com/en/guide/using-template-engines.html">Using template engines with Express</a> (dokumentacja Express) i dokuemntacją wybranego silnika.</p> +</div> + +<p>Ogólnie mówiąc powinnieneś wybrać taki silnik szablonów, który dostarcza wszystkich potrzebnych Ci funkcji i pozwala na szybkie osiągnięcie produktywności. Innymi słowy kieruj się tymi samymi regułami, którymi się kierujesz wybierając pozostałe komponenty. Podczas wyboru powinieneś rozważyć kilka kwestii:</p> + +<ul> + <li>czas osiągnięcia zadawalającej produktywności - jeśli Twój zespół posiada już jakieś doświadczenie w pracy z danym jezykiem szablonów to zapewne szybciej osiągnie sprawność w posługiwaniu się nim. Jeśli nie, to rozważ język łatwy do przyswojenia. </li> + <li>popularność i aktywność - rozważ wybór silnika popularnego i posiadającego aktywną społeczność. Jest to ważne, bo pozwala mieć wsparcie doświadczonych użytkowników w problematycznych sytuacjach pojawiających się w trakcie cyklu życia aplikacji. </li> + <li>styl - niektóre silniki szablonów korzystają ze speyficznych znaczników do oznaczania miejsc wypełnianych zawartością pośród "zwykłego" kodu HTML, a inne korzystają ze specyficznej składni (np. w postaci wcięć lub nazw bloków).</li> + <li>wydajność/ czas renderowania</li> + <li>funkcjonalność - warto uwzględnić podczas wyboru silnika także dostepność następujących funkcji: + <ul> + <li>Dziedziczenie layoutów: ten mechanizm pozwala zdefiniować szablon bazowy, który może zostać wykorzystany do budowy kolejnych poprzez przejęcie fragmentów bazowego i dodanie elementów specyficznych dla tworzonego szablonu. Jest to znacznie lepsze podejście od budowania szablonu na zasadzie dołączania wymaganych komponentów lub tworzenia za każdym razem od podstaw. </li> + <li>Wsparcie dla dyrektywy typu "include": tego typu dyrektywa pozwala na umieszczanie w szablonie innych szablonów.</li> + <li>Możliwość definiowania zmiennych i wykonywania instrukcji ieracyjnych.</li> + <li>Zdolność formatowania wartości na poziomie szablonu (np. operacja typu upper-case, formatowanie daty).</li> + <li>Zdolność generowania dokumentów wyjściowych w innych formatach od HTML (np. JSON lub XML).</li> + <li>Obsługa operacji asynchronicznych i przesyłania strumieniowego.</li> + </ul> + </li> +</ul> + +<div class="note"> +<p><strong>Wskazówka: </strong> W Intenecie znajduje się wiele zasobów, które mogą pomóc w porównaniu wiel opcji!</p> +</div> + +<p>W naszym projekcie wykorzystamy generator szablonów <a href="https://pugjs.org/api/getting-started.html">Pug</a> (poprzednio funkcjonował pod nazwą Jade), który jest najpopularniejszym narzędziem tego typu w środowisku Express/JavaScript i intalowanym wraz z generatorem aplikacji.</p> + +<h3 id="Jakiego_preprocesora_arkuszy_stylów_CSS_należy_użyć">Jakiego preprocesora arkuszy stylów CSS należy użyć?</h3> + +<p><em>Express Application Generator</em> pozwala na utworzenie projektu, który można skonfigurować do pracy z najbardziej znanymi preprocesorami stylów CSS: <a href="http://lesscss.org/">LESS</a>, <a href="http://sass-lang.com/">SASS</a>, <a href="http://compass-style.org/">Compass</a>, <a href="http://stylus-lang.com/">Stylus</a>.</p> + +<div class="note"> +<p><strong>Uwaga: </strong>CSS posiada pewne ograniczenia, które czynią definiowanie niektórych reguł bardzo trudnymi. Preprocesory dają możliwość wykorzystania bogatszej i o znacznie wiekszych możliwościach składni do definiowania reguł styli i kompilacji ich do tradycyjnego formatu CSS wykorzystywanego przez przeglądarki.</p> +</div> + +<p>Podobnie jak przy wyborze silnika szablonów, tak i przy wyborze preprocesora powinieneś się kierować preferencjami zespołu, aby osiągnąć żądaną produktywność. W naszym projekcie wykorzystamy ustawienia domyślne, czyli tzw. vanilla CSS, ponieważ nie będziemy korzystać ze zbyt skomplikowanych reguł, a czysty CSS będzie dla nas wystarczająco dobry.</p> + +<h3 id="Jakiej_bazy_danych_uzyć">Jakiej bazy danych uzyć?</h3> + +<p>Wygenerowany kod aplikacji nie jest skonfigurowany do współpracy z bazą danych. Oczywiście aplikacje <em>Express</em> moga korzystać z <a href="https://expressjs.com/en/guide/database-integration.html">dowolnego silnika bazodanowego</a> wspieranego przez środowisko Node (sam <em>Express</em> nie stawia żadnych specjalnych wymagań co do stosowanej bazy danych). Itegrację aplikacji z bazą danych omówimy w późniejszym artykule.</p> + +<h2 id="Tworzenie_projektu">Tworzenie projektu</h2> + +<p>Stworzymy na początek przykładowy projekt pod nazwą <em>express-locallibrary-tutorial </em>korzystający z generatora szablonów Pug<em> </em>i<em> </em>czystego CSS.</p> + +<p>Utwórz katalog projektu o podanej wyżej nazwie i przejdź do niego. Uruch teraz <em>Express Application Generator</em> wpisując w wierszu poleceń (terminalu) poniższą komendę:</p> + +<pre class="brush: bash notranslate">express express-locallibrary-tutorial --view=pug +</pre> + +<p>Generator aplikacji utworzy poniższą strukturę plików i katalogów.</p> + +<pre class="brush: bash notranslate"> create : express-locallibrary-tutorial\ + create : express-locallibrary-tutorial\public\ + create : express-locallibrary-tutorial\public\javascripts\ + create : express-locallibrary-tutorial\public\images\ + create : express-locallibrary-tutorial\public\stylesheets\ + create : express-locallibrary-tutorial\public\stylesheets\style.css + create : express-locallibrary-tutorial\routes\ + create : express-locallibrary-tutorial\routes\index.js + create : express-locallibrary-tutorial\routes\users.js + create : express-locallibrary-tutorial\views\ + create : express-locallibrary-tutorial\views\error.pug + create : express-locallibrary-tutorial\views\index.pug + create : express-locallibrary-tutorial\views\layout.pug + create : express-locallibrary-tutorial\app.js + create : express-locallibrary-tutorial\package.json + create : express-locallibrary-tutorial\bin\ + create : express-locallibrary-tutorial\bin\www + + change directory: + > cd express-locallibrary-tutorial + + install dependencies: + > npm install + + run the app (Bash (Linux or macOS)) + > <code>DEBUG=express-locallibrary-tutorial:* npm start +</code> + run the app (PowerShell (Windows)) +<code> > $ENV:DEBUG = "express-locallibrary-tutorial:*"; npm start +</code> + run the app (Command Prompt (Windows)): + > SET DEBUG=express-locallibrary-tutorial:* & npm start +</pre> + +<p>Na końcu zwróconych przez generator komunikatów znajdują się instrukcje w jaki sposób zainstalować wymagane pakiety (ich spis znajduje się w pliku <strong>package.json</strong>) i jak uruchomić aplikację.</p> + +<h2 id="Uruchomienie_szkieletu_aplikacji">Uruchomienie szkieletu aplikacji</h2> + +<p>W katalogu mamy na razie kompletny szkielet naszego projektu, a nasza aplikacja nie wykonuje zbyt wielu zadań. Warto jednak uruchmić ją w tej początkowej postaci, aby sprawdzić czy działa.</p> + +<ol> + <li>Na początku zainstaluj zależności(polecenie <code>install</code> pobierze wymienione w <strong>package.json</strong> pliki). + + <pre class="brush: bash notranslate">cd express-locallibrary-tutorial +npm install</pre> + </li> + <li>Uruchom aplikację. + <ul> + <li>W systemie Windows użyj tego polecenia: + <pre class="brush: bash notranslate">SET DEBUG=express-locallibrary-tutorial:* & npm start</pre> + </li> + <li>W sytemach macOS lub Linux wpisz jak poniżej: + <pre class="brush: bash notranslate">DEBUG=express-locallibrary-tutorial:* npm start +</pre> + </li> + </ul> + </li> + <li>Wpisz w przeglądarce adres <a href="http://localhost:3000/">http://localhost:3000/</a> aby dostać się do strony aplikacji.</li> +</ol> + +<p>W przeglądarce powinieneś zobaczyć stronę podobą do tej poniżej:</p> + +<p><img alt="Browser for default Express app generator website" src="https://mdn.mozillademos.org/files/14375/ExpressGeneratorSkeletonWebsite.png" style="display: block; height: 403px; margin: 0px auto; width: 576px;"></p> + +<p>Gratulacje! Twoja aplikacja Express działa i jest dostępna na Twojej lokalnej maszynie pod portem 3000.</p> + +<div class="note"> +<p><strong>Uwaga: </strong>Możesz też uruchomić aplikację korzystająć z polecenia<strong> </strong><code>npm start</code>. Ustawiając zmienną DEBUG możesz włączyć wyświetlanie komunikatów logowania i debugowania. Przykładowo podczas odświeżenia powyższej strony aplikacji zobaczysz poniższe komunikaty w oknie konsoli:</p> + +<pre class="brush: bash notranslate">>SET DEBUG=express-locallibrary-tutorial:* & npm start + +> express-locallibrary-tutorial@0.0.0 start D:\github\mdn\test\exprgen\express-locallibrary-tutorial +> node ./bin/www + + express-locallibrary-tutorial:server Listening on port 3000 +0ms +GET / 304 490.296 ms - - +GET /stylesheets/style.css 200 4.886 ms - 111 +</pre> +</div> + +<h2 id="Włączenie_restartowania_serwera_po_modyfikacji_plików">Włączenie restartowania serwera po modyfikacji plików</h2> + +<p>Jakakolwiek zmiana w naszym projekcie nie będzie widoczna dopóki nie wykonasz ponownego uruchomienia serwera. Z czasem może to być bardzo irytujące, gdy każda zmiana będzie wymagała ciągłego zatrzymywania i ponownego uruchamiania serwera. Dlatego warto poświecić nieco czasu na zautomatyzowanie tej czynności.</p> + +<p>Odpowiednim narzędziem do tego celu jest <a href="https://github.com/remy/nodemon">nodemon</a>. Zwykle jest instalowany globalnie, ale tutaj zainstalujemy go lokalnie jako zależność developerską, aby każdy developer pracujący z aplikacją miał go po zainstalowaniu projektu. Wywołaj poniższe polecenia w głównym katalogu naszego projektu::</p> + +<pre class="brush: bash notranslate">npm install --save-dev nodemon</pre> + +<p>Jeśli jednak chcesz zainstalować <a href="https://github.com/remy/nodemon">nodemon</a> globalnie, a nie tylko w swoim projekcie dodając wpis do <strong>package.json</strong>, to wpisz taką wersję polecenia: </p> + +<pre class="brush: bash notranslate">npm install -g nodemon</pre> + +<p>Gdy otworzysz plik <strong>package.json </strong>swojego projektu to powinieneś zobaczyć nową sekcję z poniższą zależnością:</p> + +<pre class="brush: json notranslate"> "devDependencies": { + "nodemon": "^2.0.4" +} +</pre> + +<p>Ponieważ nasze narzedzie nie została zainstalowane globalnie, to nie możemy go uruchomić wprost z linii poleceń (dopóki nie dodamy go do ścieżki). Możemy je jednak wywołać wprost ze skryptu NPM, bo NPM wie wszystko o zainstalowanych pakietach. Znajdź sekcję <code>scripts</code> w swoim pliku <strong>package.json</strong>. Dodaj do niej dwa wiersze ze skryptami "devstart" i "serverstart", Pamiętaj o dodaniu na końcu każdego wiersza (oprócz ostatniego) znaku przecinka: </p> + +<pre class="brush: json notranslate"> "scripts": { + "start": "node ./bin/www"<strong>,</strong> +<strong> "devstart": "nodemon ./bin/www", + "serverstart": "</strong>DEBUG=express-locallibrary-tutorial:* npm <strong>run devstart"</strong> + }, +</pre> + +<p>Możemy teraz uruchomić serwer w prawie taki sam sposób jak poprzednio, ale przy pomocy polecenia <code>devstart</code>: </p> + +<ul> + <li>W systemie Windows wpisz polecenie w takiej postaci: + <pre class="brush: bash notranslate">SET DEBUG=express-locallibrary-tutorial:* & npm <strong>run devstart</strong></pre> + </li> + <li>W systemach macOS lub Linux użyj tej postaci: + <pre class="brush: bash notranslate">DEBUG=express-locallibrary-tutorial:* npm <strong>run devstart</strong> +</pre> + </li> +</ul> + +<div class="note"> +<p><strong>Uwaga:</strong> Od tej chwili każda zmiana jakiegokolwiek pliku projektu powoduje restart serwera (możesz też zrestartować serwer wpisując w dowolnym momencie polecenie rs w terminalu). Nadal jednak będziesz musiał odświeżać stronę w przeglądarce.</p> + +<p>Od teraz musimy uruchamiać skrypty poleceniem "<code>npm run <em><scriptname></em></code>" zamiast zwykłego <code>npm start</code>, ponieważ „start” jest w rzeczywistości poleceniem NPM, które jest odwzorowane na skrypt o takiej nazwie. Mogliśmy zamienić polecenie w skrypcie <em>start</em>, ale podczas programowania chcemy używać tylko <em>nodemon</em>, więc sensowne jest utworzenie nowego polecenia skryptu.</p> + +<p>Dodanie polecenia <code>serverstart</code> w sekji skryptów pliku <strong>package.json</strong> jest dobrym rozwiązaniem, które pozwala uniknąć wpisywania długim poleceń uruchamiających serwer. Zwróć uwagę, że niektóre konkretne polecenia dodane do skryptu działają tylko w systemie macOS lub Linux.</p> +</div> + +<h2 id="Wygenerowany_projekt">Wygenerowany projekt</h2> + +<p>Przyjrzyjmy się bliżej projektowi, który stworzyliśmy.</p> + +<h3 id="Struktura_katalogów">Struktura katalogów</h3> + +<p>Utworzony projekt wraz z zainstalowanymi zależnościami ma przedstawioną poniżej strukturę (pliki są elementami z prefiksem "/").</p> + +<p>Plik <strong>package.json </strong>definiuje spis wymaganych przez naszą aplikację pakietów oraz zawiera wiele innych informacji o aplikacji. W pliku tym są też zdefiniowane skrypty, w tym też skrypt startowy, który wywołuje punkt wejścia aplikacji, czyli plik JavaScript <strong>/bin/www</strong>. Skrypt ten po ustawieniu mechanizmu obslugi błędów uruchamia plik <strong>app.js</strong>, który wykonuje resztę pracy.</p> + +<p>W katalogu <strong>/routes</strong> znajdują się moduły obsługujące ścieżki aplikacji. Szablony generowanych stron przechowywane są w katalogu <strong>/views</strong>. </p> + +<pre class="notranslate">/express-locallibrary-tutorial + <strong>app.js</strong> + /bin + <strong>www</strong> + <strong>package.json</strong> + <strong>package-lock.json</strong> + /node_modules + [about 6700 subdirectories and files] + /public + /images + /javascripts + /stylesheets + <strong>style.css</strong> + /routes + <strong>index.js</strong> + <strong>users.js</strong> + /views + <strong>error.pug</strong> + <strong>index.pug</strong> + <strong>layout.pug</strong> + +</pre> + +<p>W kolejnych sekcjach znajdziesz więcej szczegółów dotyczących plików projektu. </p> + +<h3 id="package.json">package.json</h3> + +<p>Plik <strong>package.json</strong>:</p> + +<pre class="brush: json notranslate">{ + "name": "express-locallibrary-tutorial", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "cookie-parser": "~1.4.4", + "debug": "~2.6.9", + "express": "~4.16.1", + "http-errors": "~1.6.3", + "morgan": "~1.9.1", + "pug": "2.0.0-beta11" + }, + "devDependencies": { + "nodemon": "^2.0.4" + } +} +</pre> + +<p>Sekcja zależności zawiera paczkę <em>express </em>i wybrany przez nas silnik szablonów (<em>pug</em>). Oprócz tego znajdują się w niej jeszcze inne paczki przydatne w aplikacjach webowych:</p> + +<ul> + <li><a href="https://www.npmjs.com/package/cookie-parser">cookie-parser</a>: służy do parsowania ciasteczek i zapewnia przeniesienie ich do <code>req.cookies</code> (zasadniczo daje możliwość wygodnego dostępu do informacji w nagłówkach cookie)</li> + <li><a href="https://www.npmjs.com/package/debug">debug</a>: niewielka paczka służąca do debugowania. której mechanizm jest wzorowany na technice wykorzystywanej w rdzeniu środowiska Node.</li> + <li><a href="https://www.npmjs.com/package/morgan">morgan</a>: Narzędzie do rejestrowania zdarzeń (logger) w warstwie obsługi żądań HTTP.</li> + <li><a href="https://www.npmjs.com/package/http-errors">http-errors</a>: Tworzenie błędów HTTP w razie potrzeby (zgodnych z obsługa błędów w aplikacjach <em>express</em>).</li> +</ul> + +<p>W sekcji scripts zdefiniowany jest skrypt "start", który jest tym samym skryptem wywoływanym poleceniem <code>npm start</code>, gdy chcemy uruchomić serwer. Z definicji tego skryptu wynika, że uruchomia on plik <strong>./bin/www </strong>z kodem JavaScript. </p> + +<pre class="brush: json notranslate"> "scripts": { + "start": "node ./bin/www", + "devstart": "nodemon ./bin/www", + "serverstart": "DEBUG=express-locallibrary-tutorial:* npm run devstart" + }, +</pre> + +<p>Pozostałe skrypty <em>devstart</em> i <em>serverstart</em> możemy wykorzystywać do uruchomienia tego samego pliku <strong>./bin/www</strong> ale z użyciem <em>nodemon</em> niż <em>node</em> (jak zostało to wyjaśnione w sekcji <a href="#Enable_server_restart_on_file_changes">Włączenie restartowania serwera po modyfikacji plików</a>).</p> + +<h3 id="Plik_www">Plik www</h3> + +<p>Plik <strong>/bin/www</strong> jest punktem wejścia aplikacji! Pierwszą rzeczą jaką wykonuje ten plik to funkcja <code>require()</code>, która kieruje do prawdziwego punktu zaczynającego wykonywanie aplikacji (<strong>app.js</strong>, w głównym katalogu projektu), w którym następuje przygotowanie i zwrócenie obiektu aplikacji <code><a href="http://expressjs.com/en/api.html">express()</a></code>.</p> + +<pre class="brush: js notranslate">#!/usr/bin/env node + +/** + * Module dependencies. + */ + +<strong>var app = require('../app');</strong> +</pre> + +<div class="note"> +<p><strong>Uwaga:</strong> <code>require()</code> jest funkcją globalną środowiska Node, która importuje moduł do bieżącego pliku. W powyższym kodzie moduł <strong>app.js</strong> został podany z użyciem ścieżki względnej i z pominięciem opcjonalnego rozszerzenia <strong>.js</strong>.</p> +</div> + +<p>Pozostała część kodu tego pliku konfiguruje serwer HTTP z aplikacją pracującą pod wskazanym portem (numer portu jest zdefiniowany w zmiennej środowiskowej lub przyjmowana jest wartość 3000 jeśli brak takiej zmiennej). W dalszej części następuje uruchomienie nasłuchiwania i raportowania błędów serwera i połączeń. Na razie nie musisz znać wszystkich szczegółów tego kodu (wszystko w tym pliku jest standardowym kodem), choć jeśli jesteś zainteresowany możesz go przejrzeć.</p> + +<h3 id="app.js">app.js</h3> + +<p>Ten plik jest odpowiedzialny za utworzenie obiektu aplikacji (pod konwencjonalną nazwą <code>app</code>), jej skonfigurowanie wraz z warstwami pośrednimi i wyeksportowanie jej z modułu. Kod poniżej zawiera tę cześć pliku app.js, która zawiera tworzenie i eksportowanie obiektu aplikacji:</p> + +<pre class="brush: js notranslate"><code>var express = require('express'); +var app = express(); +... +</code>module.exports = app; +</pre> + +<p>Powrót do punktu wejściowego, czyli do pliku <strong>www</strong>, następuje w linii zawierającej <code>module.exports</code>, która eksportuje obiekt app aplikacji i zwraca go do wywołującego kodu, który ten moduł zaimportował.</p> + +<p>Czas teraz na szczegóły pliku app.js. Na początku importowne są dość użyteczne moduły przy pomocy funkcji <code>require()</code>, w tym <em>http-errors</em>, <em>express</em>, <em>morgan</em> i <em>cookie-parser, </em>które wcześniej zostały pobrane przez menadżera NPM, oraz pakiet <em>path</em>, który jest częścią środowiska Node i odpowiada za parsowanie ścieżek do plików i katalogów. </p> + +<pre class="brush: js notranslate">var createError = require('http-errors'); +var express = require('express'); +var path = require('path'); +var cookieParser = require('cookie-parser'); +var logger = require('morgan'); +</pre> + +<p>Kolejne funkcje <code>require()</code>, importują moduły z katalogu <em>routes</em>. Zawierają one kody źródłowe obsługujące zbióry ścieżek naszej aplikacji (URL). Gdy będziemy rozbudowywać aplikację o kolejne ścieżki, na przykład zwracają listę wszystkich książek naszej biblioteki, to będziemy musieli dodać nowy plik z definicją operacji wykonywanych pod tą ścieżką. </p> + +<pre class="brush: js notranslate">var indexRouter = require('./routes/index'); +var usersRouter = require('./routes/users'); +</pre> + +<div class="note"> +<p><strong>Uwaga:</strong> W tym miejscu tylko zaimportowaliśmy moduły, na razie nie korzystamy z tych ścieżek (nastapi to później). </p> +</div> + +<p>Następnie tworzymy obiekt <em>app </em>za pomocą zaimportowanego modułu <em>express</em>, po czym konfigurujemy go do pracy z wybranym silnikiem szablonów. W pierwszym kroku określa się lokalizację szablonów poprzez przypisanie katalogu do zmiennej 'views'. W drugim należy podać nazwę wykorzystywanej biblioteki szablonów (w naszym przypadku jest to "pug"). </p> + +<pre class="brush: js notranslate">var app = express(); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'pug'); +</pre> + +<p>Następna sekcja zawiera szereg wywołań metody <em>use </em>na obiekcie aplikacji, których zadaniem jest dodanie bibliotek wykorzystywanych w warstwie pośredniej całego łańcucha przetwarzania żądań. Oprócz dołączonych wcześniej modułów zewnętrznych, wykorzystujemy także moduł <code>express.static</code>, którego zadaniem jest obsługa plików statycznych z katalogu <strong>/public</strong> naszego projektu. </p> + +<pre class="brush: js notranslate">app.use(logger('dev')); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); +<strong>app.use(express.static(path.join(__dirname, 'public')));</strong> +</pre> + +<p>Po skonfigurowaniu warstwy pośredniej możemy dodać (poprzednio już zaimportowane) nasze skrypty obsługujące żądania ścieżek. Zaimportowane pliki definiują poszczególne ścieżki dla różnych części naszej aplikacji:</p> + +<pre class="brush: js notranslate">app.use('/', indexRouter); +app.use('/users', usersRouter); +</pre> + +<div class="note"> +<p><strong>Uwaga:</strong> Podane powyżej ścieżki (<code>'/'</code> i '<code>/users'</code>) są traktowane jako przedrostki tras zdefiniowanych w importowanych plikach. Na przykład, jeśli zaimportowany moduł <strong>users</strong> definiuje ścieżkę względną <code>/profile</code>, to dostęp do tej ścieżki będzie możliwy pod <code>/users/profile</code>. Ścieżki zostaną dokładniej omówione w następnych artykułach.</p> +</div> + +<p>Końcowym etapem konfigurowania warstwy pośredniej jest dodanie obsługi błędów i odpowiedzi HTTP 404.</p> + +<pre class="brush: js notranslate">// catch 404 and forward to error handler +app.use(function(req, res, next) { + next(createError(404)); +}); + +// error handler +app.use(function(err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); +</pre> + +<p>Obiekt aplikacji Express jest teraz w pełni skonfigurowany. Ostatnim działaniem w skrypcie jest wyeksportowanie obiektu z bieżącego modułu (w ten sposób staje się on dostępny w pliku <strong>/bin/www </strong>po zaimportowaniu).</p> + +<pre class="brush: js notranslate">module.exports = app;</pre> + +<h3 id="Ścieżki">Ścieżki</h3> + +<p>Plik definiujący obsługę żądań kierowanych do ścieżki <strong>/routes/users.js</strong> znajduje się poniżej (struktura wszystkich plików ścieżek jest bardzo podobna, dlatego nie ma potrzeby oglądania pliku <strong>index</strong>). Na początku znajduje się znana już funkcja importująca moduł <em>express</em>, z którego pobierany jest obiekt <code>express.Router</code> . Po zdefiniowaniu obsługi żądania, obiekt rutera jest exportowany z modułu (dzięki czemu może być zaimportowany w <strong>app.js</strong>). </p> + +<pre class="brush: js notranslate">var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +<strong>router.get('/', function(req, res, next) { + res.send('respond with a resource');</strong> +}); + +module.exports = router; +</pre> + +<p>Ruter definiuje metodę, która będzie wywoływana w chwily pojawienia się żądania <code>GET</code> protokołu HTTP skierowanego pod adres zgodny z wzorcem. Pełna ścieżka do tej metody zostanie zdefiniowana gdy moduł ('<code>/users</code>') zostanie zaimportowany i zostanie dodany przedrostek ('<code>/</code>') w module importujacym. Krótko mówiąc, ściezka zostanie użyta, gdy skierowane zostanie żądanie z URL zawierającym <code>/users/</code>. </p> + +<div class="note"> +<p><strong>Wskazówka: </strong>Wypróbuj działanie rutera uruchamiając serwer i odwiedzając w przeglądarce URL <a href="http://localhost:3000/users/">http://localhost:3000/users/</a>. Powinieneś zobaczyć komunikat: 'respond with a resoure'. </p> +</div> + +<p>Interesującym elementem w kodzie metody obsługującej żądanie GET jest trzeci argument <code>next</code>, co świadczy o tym, że jest to metoda warstwy poredniej a nie prosta funkcja zwrotna. Chociaż na razie w metodzie nie korzystamy z tego argumentu to być może będzie potrzebny w przyszłości, gdy zechsze dodać wiecej metod obsługujących ścieżkę <code>'/'.</code></p> + +<h3 id="Widoki_szablony">Widoki (szablony)</h3> + +<p>Widoki (szablony) są przechowywane w katalogu <code>/views</code> (tak jak zdefiniowano to w pliku <strong>app.js</strong>) i posiadają rozszerzenie .<strong>pug</strong>. Metoda <code><a href="http://expressjs.com/en/4x/api.html#res.render">Response.render()</a></code> jest wykorzystywana do renderowania strony HTML na podstawie szablonu i dostarczonych do niego wartości zmiennych, po czym gotowy dokument jest wysyłany do jako odpowiedź żądania. W znajdującym się kodzie poniżej pochodzącym z pliku możesz obaczyć jak funkcja obsługi żądania ścieżki renderuje szablon "index" na podstawie przekazanej zmiennej "title". </p> + +<pre class="brush: js notranslate">/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); +</pre> + +<p>Szablon "index" (<strong>index.pug</strong>) jest przedsatwiony poniżej. Składnię szablonów omówimy poźniej. To co na razie powinieneś wiedzieć to to, że zmienna <code>title</code> (zawierająca napisz '<code>Expres</code>s') została wstawiona w określonym miejscu szablonu.</p> + +<pre class="notranslate">extends layout + +block content + h1= title + p Welcome to #{title} +</pre> + +<h2 id="Challenge_yourself">Challenge yourself</h2> + +<p>Create a new route in <strong>/routes/users.js</strong> that will display the text "<em>You're so cool"</em> at URL <code>/users/cool/</code>. Test it by running the server and visiting <a href="http://localhost:3000/users/cool/">http://localhost:3000/users/cool/</a> in your browser</p> + +<ul> +</ul> + +<h2 id="Summary">Summary</h2> + +<p>You have now created a skeleton website project for the <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Local Library</a> and verified that it runs using <em>node</em>. Most importantly, you also understand how the project is structured, so you have a good idea where we need to make changes to add routes and views for our local library.</p> + +<p>Next, we'll start modifying the skeleton so that it works as a library website.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://expressjs.com/en/starter/generator.html">Express application generator</a> (Express docs)</li> + <li><a href="https://expressjs.com/en/guide/using-template-engines.html">Using template engines with Express</a> (Express docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li> +</ul> |
