Tworzenie aplikacji w języku JavaScript Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak Wyższa Szkoła Zarządzania i Bankowości w Krakowie http://artemis.wszib.edu.pl/~polak/ Materiały dla studentów Informatyki WSZiB w Krakowie Dr inż. Stanisław Polak 1 Przedmiot: Aplikacje internetowe Plan prezentacji Wprowadzenie Aplikacja 3 Dr inż. Stanisław Polak Przedmiot: Aplikacje internetowe Wprowadzenie Node.js Ogólna charakterystyka Udostępnia JavaScript po stronie serwera Używa V8 JavaScript Engine System do tworzenia serwisów sieciowych z asynchronicznym WE/WY Wykorzystuje paradygmat programowania sterowanego zdarzeniami Nadaje się dobrze do pisania aplikacji, które wymagają komunikacji w czasie rzeczywistym pomiędzy przeglądarką a serwerem Pojedyncza instancja Node.js działa jako pojedynczy wątek Pętla zdarzeń podmiot, który obsługuje / przetwarza zdarzenia zewnętrzne i konwertuje je na wywołania funkcji zwrotnych. Przykład 1 #!/usr / bin / node console. log ( " " ) ; Uruchamianie skryptu $ node hello.js $ node hello hello.js Uruchamianie skryptu $ chmod 755 hello.js $./hello.js Uruchamianie trybu interaktywnego Rysunek: Schemat działania pętli zdarzeń w Node.js Dr inż. Stanisław Źródło: Polak http://www.aaronstannard.com/post/011/1/1/intro-to-nodejs-for-net-developers.aspx 3 Przedmiot: Aplikacje internetowe $ node > console.log("") undefined > + > ^D $ Dr inż. Stanisław Polak Przedmiot: Aplikacje internetowe
Wprowadzanie i wyprowadzanie danych 1 process. stdout. write ( 1 ) ; process. stdout. write ( ) ; 3 console. log ( 3 ) 5 / 6 c o n s o l e. l o g = f u n c t i o n (d) { 7 p r o c e s s. s t d o u t. w r i t e ( d + \n ) ; 8 }; 9 / 10 11 process. stdin. setencoding ( utf8 ) ; 1 process. stdout. write ( Wprowad ź dane - naci śnięcie ^D koń czy ich wprowadzanie \n ) ; 13 process. stdin. on ( readable, function ( ) { 1 var chunk = process. stdin. read ( ) ; 15 if ( chunk!== null ) { 16 process. stdout. write ( Wczytano : + chunk ) ; 17 } 18 }) ; 19 console.log( Osiągnięto koniec skryptu ) ; Uruchamianie $ node skrypt.js 13 Wprowadź dane - naciśnięcie ^D kończy ich wprowadzanie Osiągnięto koniec skryptu abc Wczytano: abc def Wczytano: def skrypt.js Dostęp do zmiennych środowiskowych, obsługa linii komend 1 // Odczyt warto ś c i zmiennej ś rodowiskowej HOME console. log ( "Twój katalog domowy to: "+process. env [ HOME ] ) ; 3 //Wyś w i e t l e n i e warto ś c i argument ów l i n i i komend 5 console. log ( " Argumenty linii komend to:" ) ; 6 process. argv. foreach ( function ( wartosc, indeks, tablica ) { 7 console. log ( \t +indeks + : + wartosc ) ; 8 }) ; Uruchamianie $ node skrypt.js 1 b= Twój katalog domowy to: /home/polak Argumenty linii komend to: 0: node 1: /home/polak/skrypt.js : 1 3: b= skrypt.js Dr inż. Stanisław Polak 5 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 6 Przedmiot: Aplikacje internetowe Moduł Tworzenie Moduł Korzystanie 1 var mojmodul = require( mojmodul ) ; // mojmodul = require(./mojmodul ) ; 3 / / console. log ( mojmodul. zmienna1 ) ; // u n d e f i n e d 5 console. log ( mojmodul. zmienna ) ; // 6 console. log ( mojmodul. zmienna3 ) ; // u n d e f i n e d 7 console. log ( mojmodul. zmienna ) ; // 8 console. log ( mojmodul. fun1 ( ) ) ; // fun1 9 console. log ( mojmodul. fun ( ) ) ; //Bł ąd 10 / / 11 console. log (mojmodul) ; //{ zmienna:, zmienna:, fun1: [Function] } 1 console. log (mojmodul ( ) ) ; //Błąd 13 skrypt.js 1 $ export NODE_PATH = kat 1 :kat :... :kat N 1 zmienna1 = 1 ; exports. zmienna = ; 3 var zmienna3 = 3 ; var zmienna ; 5 module.exports. zmienna = ; 6 var exports. zmienna5 = 5 ; // SyntaxError : Unexpected token. 7 exports. fun1 = function ( ) { 8 return "fun1 " ; 9 }; 10 fun = function ( ) { 11 return "fun " ; 1 }; 13 console. log (module) ; 1 / Module { 15..., 16 exports : { zmienna :, zmienna :, fun1 : [ F u n c t i o n ] }, 17... } / 18 exports = function ( ) { 19 return "fun3 " ; 0 } 1 module. exports = function ( ) { return "fun " ; 3 } console. log (module.exports) ; //{ zmienna:, zmienna:, fun1: [Function] } 5 console. log (exports) ; //{ zmienna:, zmienna:, fun1: [Function] } 6 console. log (module.exports == exports) ; //true node modules/mojmodul.js Obsługa pakietów $ npm install nazwa_pakietu # Moduły ->./node modules/ # Pliki wykonywalne ->./node modules/.bin/ # Manuale -> nie są instalowane $ npm install -g nazwa_pakietu # Moduły -> {prefix}/lib/node modules/ # Pliki wykonywalne -> {prefix}/bin/ # Manuale -> {prefix}/share/man/ # {prefix} = np. /usr $ npm link nazwa pakietu # Wykonuje: ln -s {prefix}/lib/node modules/nazwa pakietu/./node modules/ Dr inż. Stanisław Polak 7 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 8 Przedmiot: Aplikacje internetowe
Obsługa plików 1 var fs = require ( "fs" ) ; // Sprawd ź czy p l i k i s t n i e j e 3 try{ fs. accesssync( plik.txt ) ; } catch ( err ){ fs. writefilesync( plik.txt, 1 ) ; } 5 fs. readfile( plik. txt, utf -8, function ( error, data ) { 6 if ( error ) throw error ; 7 console. log ( " Odczytana wartość: "+ data ) ; 8 }) ; 9 10 fs. writefile( plik. txt,, function ( error ) { 11 if ( error ) throw error ; 1 console. log ( Zapisano wartość ) ; 13 }) ; Uruchamianie Wersja nieprawidłowa $ node skrypt1.js Zapisano wartość Odczytana wartość: 1 var fs = require ( "fs" ) ; try{ fs. accesssync ( plik.txt ) } 3 catch ( err ){ fs. writefilesync ( plik.txt, 1 ) ; } 5 fs. readfile ( plik. txt, utf -8, function ( error, data ) { 6 if ( error ) throw error ; 7 console. log ( " Odczytana wartość: "+data ) ; 8 9 fs. writefile ( plik. txt,, function ( error ) { 10 if ( error ) throw error ; 11 console. log ( Zapisano wartość ) ; 1 }) ; 13 }) ; Uruchamianie $ node skrypt.js Odczytana wartość: 1 Zapisano wartość Wersja prawidłowa Dr inż. Stanisław Polak 9 Przedmiot: Aplikacje internetowe Obsługa bazy danych SQLite 3 1 var sqlite3 = require ( sqlite3 ) ; 3 var db = new sqlite3. Database ( : memory : ) ; //Zwraca obiekt Database 5 db. serialize( function ( ) { 6 db. run( "CREATE TABLE products (info TEXT )" ) ; 7 var stmt = db. prepare( "INSERT INTO products VALUES (?) " ) ; //Zwraca obiekt Statement 8 for ( var i = 0 ; i < ; i++) { 9 stmt. run( " Produkt " + i ) ; 10 } 11 stmt. finalize ( ) ; 1 13 jsondata = { products : [ ] }; 1 db. each( "SELECT rowid AS id, info FROM products ", function ( err, row ) { 15 jsondata. products. push ({ id : row. id, info : row. info }) ; 16 }, function ( ) { 17 console. log ( JSON. stringify ( jsondata ) ) ; //JSON. s t r i n g i f y wbudowana f u n k c j a JS 18 } 19 ) ; 0 }) ; 1 db. close ( ) ; Instalacja i uruchamianie bd.js $ npm install sqlite3 $ node bd.js {"products":[{"id":1,"info":"produkt 0"},{"id":,"info":"Produkt 1"}]} Materiały dla studentów Informatyki WSZiB w Krakowie Dr inż. Stanisław Polak 10 Przedmiot: Aplikacje internetowe Tworzenie dodatków (addons) w C++ Przykład 1 / Poniż szy program jest odpowiednikiem nast ę pującego kodu JS : 3 e x p o r t s. h e l l o = f u n c t i o n ( ) { r e t u r n world ; }; / 5 6 #include <node. h> 7 8 using namespace v8 ; 9 10 void Method ( const FunctionCallbackInfo<Value>& args ) { 11 Isolate isolate = Isolate : : GetCurrent ( ) ; 1 HandleScope scope ( isolate ) ; 13 args. GetReturnValue ( ). Set ( String : : NewFromUtf8 ( isolate, " world " ) ) ; 1 } 15 16 void init ( Handle<Object> exports ) { 17 NODE_SET_METHOD ( exports, " hello ", Method ) ; 18 } 19 0 NODE_MODULE ( hello, init ) // t u t a j n i e ma ś r e d n i k a hello.cc Instalacja programu node-gyp $ npm install -g node-gyp 1 { " targets " : [ 3 { "target_name " : "hello ", 5 " sources " : [ " hello.cc" ] 6 } 7 ] 8 } binding.gyp 1 var addon = require (./ build / Release / hello ) ; console. log ( addon. hello ( ) ) ; hello.js Kompilacja i uruchomienie $ node-gyp configure $ node-gyp build $ node hello.js world Dr inż. Stanisław Polak 11 Przedmiot: Aplikacje internetowe Szkielet skryptu 1 var http = require ( " http " ) ; 3 function requestlistener (request, response) { console. log ( "Pojawi ło się żą danie od klienta " ) ; 5 response. writehead (00, {"Content -Type " : "text / plain "}) ; 6 response. write ( " " ) ; 7 response. end ( ) ; 8 } 9 var serwer = http. createserver ( requestlistener ) ; 10 serwer. listen (8080) ; 11 console. log ( "Uruchomiono serwer " ) ; serwer.js Sprawdzenie działania Z poziomu terminala $ node serwer.js & Uruchomiono serwer $ curl http://localhost:8080 Pojawiło się żądanie od klienta 1 var http = require ( " http " ) ; 3 http. createserver ( function ( request, response ) { console. log ( "Pojawi ło się żą danie od klienta " ) ; 5 response. writehead ( 00, {"Content -Type " : "text / plain "}) ; 6 response. write ( " " ) ; 7 response. end ( ) ; 8 }). listen (8080) ; 9 console. log ( "Uruchomiono serwer " ) ; Wersja alternatywna Rysunek: Z poziomu przeglądarki WWW Dr inż. Stanisław Polak 1 Przedmiot: Aplikacje internetowe
Obsługa parametrów URL 1 var url = require ( " url " ) ;... 3 function requestlistener ( request, response ) { console. log ( "Pojawi ło się żą danie od klienta " ) ; 5 var url_parts = url. parse ( request. url, true ) ; // Pass t r u e as t h e second argument to a l s o p a r s e the query string using the querystring module. Defaults to f a l s e. 6 console. log ( url_parts ) ; 7 8 response. writehead ( 00, {"Content -Type " : "text /plain "}) ; 9 response. write ( \n ) ; 10 response. write ( url_parts. pathname+ \n ) ; 11 response. write ( Login : +url_parts. query [ login ]+ \n ) ; 1 response. write ( Has ło: +url_parts. query [ haslo ]+ \n ) ; 13 response. end ( ) ; 1 } 15... Na wyjściu Terminal 1 $ node serwer.js Uruchomiono serwer Pojawiło się żądanie od klienta {... search:?login=jan&haslo=kowalski+%8nowak%9, query: { login: Jan, haslo: Kowalski (Nowak) }, pathname: /abc, path: /abc?login=jan&haslo=kowalski+%8nowak%9, href: /abc?login=jan&haslo=kowalski+%8nowak%9 } serwer.js Terminal $ curl http://localhost:8080/abc?login=jan&haslo= Kowalski+%8Nowak%9 /abc Jan Kowalski (Nowak) Dr inż. Stanisław Polak 13 Przedmiot: Aplikacje internetowe Obsługa formularzy Kodowanie application/x-www-form-urlencoded 1 var qs = require ( querystring ) ;... 3 function requestlistener ( request, response ) { var url_parts = url. parse ( request. url, true ) ; 5 if ( url_parts. pathname == /form ){ // g e n e r o w a n i e f o r m u l a r z a 6 response. writehead (00, {"Content -Type " : "text /html "}) ; 7 response. write ( <form method ="POST " action ="/ submit "> ) ; 8 response. write ( <input name =" login " value =" Jan "> ) ; 9 response. write ( <input name =" haslo " value =" Kowalski ( Nowak ) ąę"> ) ; 10 response. write ( <input type =" submit "> ) ; 11 response. write ( </form > ) ; 1 response. end ( ) ; 13 } 1 if ( url_parts. pathname == /submit ) { // przetwarzanie zawarto ś ci formularza 15 if ( request. method== GET ) { 16 response. writehead ( 00, {"Content -Type " : "text /plain "}) ; 17 response. write ( url_parts. query [ login ]+ \n ) ; // przegl ądarka wypisze : Jan\n 18 response. write ( url_parts. query [ haslo ]+ \n ) ; // przegl ądarka wypisze : Kowalski (Nowak ) ąę \n 19 response. end ( ) ; 0 } 1 else if ( request. method== POST ) { var body= ; 3 request. on( data, function ( data ) { body +=data ; 5 }) ; 6 request. on( end, function ( ){ 7 var data = qs. parse( body ) ; //body z a w i e r a l o g i n=jan&h a s l o=k o w a l s k i+%8nowak%9+%c%85% C%99 8 response. writehead ( 00, {"Content -Type " : "text /plain "}) ; 9 response. write ( data [ login ]+ \n ) ; // przegl ądarka wypisze : Jan\n 30 response. write ( data [ haslo ]+ \n ) ; // przegl ądarka wypisze : Kowalski (Nowak ) ąę\n 31 response. end ( ) ; 3 }) ; 33 } 3 } 35 } Dr inż. 36 Stanisław... Polak 1 Przedmiot: Aplikacje internetowe Wolnostojący serwer WWW Express Ogólna charakterystyka Instalacja i uruchamianie $ npm install http-server -g $ http-server -h usage: http-server [path] [options] options: -p Port to use [8080] -a Address to use [0.0.0.0] -d Show directory listings [true] -i Display autoindex [true] -e --ext Default file extension if none supplied [none] -s --silent Suppress log messages from output -h --help Print this list and exit. -c Set cache time (in seconds). e.g. -c10 for 10 seconds. To disable caching, use -c-1. $ http-server Starting up http-server, serving./ on port: 8080 Hit CTRL-C to stop the server Najpopularniejszy framework do tworzenia aplikacji WWW Inspirowany projektem Ruby Sinatra Moduł node.js instalacja npm install -g express API oparte na JSON Dr inż. Stanisław Polak 15 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 16 Przedmiot: Aplikacje internetowe
Użyte narzędzia oraz języki Tworzenie szkieletu aplikacji 1 $ mkdir MySite $ cd MySite 3 $ vi package. json $ npm install #i n s t a l o w a n i e z a l e ż no ś c i Pug System szablonów Treść szablonu jest tłumaczona na HTML CSS 1 { " name " : " MySite ", 3 " version " : " 0.0.1 ", " private " : " true ", 5 " dependencies " : { 6 " express " : "*", 7 " pug " : "*", 8 " morgan " : "*" 9 } 10 } package.json Dr inż. Stanisław Polak 17 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 18 Przedmiot: Aplikacje internetowe Główny plik aplikacji 1 var express = require ( express ), logger = require ( morgan ) ; 3 var app = express ( ) ; 5 var router = express. Router ( ) ; 6 app. set ( views, dirname + / views ) ; 7 app. set ( view engine, pug ) ; 8 app. use ( logger ( dev ) ) ; 9 app. use ( express. static ( dirname + / public ) ) ; 10 router. get ( /, function ( req, res ) { 11 res. render ( index, 1 { title : Przyk ład } 13 ) 1 }) ; 15 app. use ( /, router ) ; 16 app. listen (3000) ; app.js Dr inż. Stanisław Polak 19 Przedmiot: Aplikacje internetowe Pliki Pug 1 extends layout. pug 3 block content p 5 Witaj Świecie 6 Witaj Świecie 7 p 8 Witaj Świecie 9 10 block sidebar 11 h1 Nag ł ówek 1 p 13 Tre ś ć ramki views/index.pug 1 doctype html html 3 head title #{title} 5 link ( rel= stylesheet, href= / stylesheets / style.css ) 6 body 7 header 8 h1 Moja strona 9 main 10 block content 11 aside 1 block sidebar 13 footer 1 p Aplikacja stworzona w oparciu o framework Express views/layout.pug Materiały dla studentów Informatyki WSZiB w Krakowie Dr inż. Stanisław Polak 0 Przedmiot: Aplikacje internetowe
Plik CSS Uruchamianie aplikacji 1 aside { float : right ; 3 border : 5px solid blue ; padding : 1px ; 5 margin bottom : 1 px ; 6 width : 0%; 7 } 8 main { 9 float : left ; 10 background color : #f ; 11 padding : 5px ; 1 width : 75%; 13 } 1 footer { 15 clear : both ; 16 border style : dotted ; 17 } 18 header { 19 text align : center ; 0 } 1 $ node app GET / 30 87.588 ms 3 GET / stylesheets / style. css 30.78 ms public/stylesheets/style.css Dr inż. Stanisław Polak 1 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak Przedmiot: Aplikacje internetowe Polecenie express Generowanie aplikacji Użycie polecenia express 1 $ npm install g express generator $ express help 3 Usage : express [ options ] [ dir ] 5 Options : 6 7 h, help output usage information 8 version output the version number 9 e, ejs add ejs engine support 10 pug add pug engine support 11 hbs add handlebars engine support 1 H, hogan add hogan. js engine support 13 v, view <engine> add view <engine> support ( ejs hbs hjs jade pug twig vash ) ( defaults to jade ) 1 c, css <engine> add stylesheet <engine> support ( less stylus compass sass ) ( defaults to plain css ) 15 git add. gitignore 16 f, force force on non empty directory 1 $ express view=pug MySite create : MySite 3 create : MySite / package. json create : MySite / app. js 5 create : MySite / public 6 create : MySite / routes 7 create : MySite / routes / index. js 8 create : MySite / routes / users. js 9 create : MySite / views 10 create : MySite / views / index. pug 11 create : MySite / views / layout. pug 1 create : MySite / views / error. pug 13 create : MySite / bin 1 create : MySite / bin / www 15 create : MySite / public / javascripts 16 create : MySite / public / images 17 create : MySite / public / stylesheets 18 create : MySite / public / stylesheets / style. css 19 0 install dependencies : 1 $ cd MySite && npm install 3 run the app : $ DEBUG=mysite : npm start Dr inż. Stanisław Polak 3 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak Przedmiot: Aplikacje internetowe
Plik package.json Główny plik aplikacji app.js 1 { " name " : " mysite ", 3 " version " : " 0.0.0 ", " private " : true, 5 " scripts " : { 6 " start " : " node./ bin / www " 7 }, 8 " dependencies " : { 9 "body - parser " : " ~1.16.0 ", 10 " cookie - parser " : " ~1..3 ", 11 " debug " : " ~.6.0 ", 1 " express " : " ~.1.1 ", 13 " morgan " : " ~1.7.0 ", 1 "pug " : "~.0.0 - beta10 ", 15 "serve - favicon " : " ~.3. " 16 } 17 } 1... var index = require (./ routes / index ) ; 3 var users = require (./ routes / users ) ; 5 var app = express ( ) ; 6... 7 app. use ( /, index ) ; 8 app. use ( / users, users ) ; 9... Dr inż. Stanisław Polak 5 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 6 Przedmiot: Aplikacje internetowe Pliki z definicją tras Pozostałe (wygenerowane) pliki 1 var express = require ( express ) ; var router = express. Router ( ) ; 3 / GET home page. / 5 router. get ( /, function ( req, res, next ) { 6 res. render ( index, { title : Express }) ; 7 }) ; 8 9 module. exports = router ; 1 extends layout. pug 3 block content h1= title 5 p Welcome to #{title} views/index.pug 1 doctype html html 3 head title= title 5 link ( rel= stylesheet, href= / stylesheets / style.css ) 6 body 7 block content views/layout.pug routes/index.js 1 var express = require ( express ) ; var router = express. Router ( ) ; 3 / GET u s e r s l i s t i n g. / 5 router. get ( /, function ( req, res, next ) { 6 res. send ( respond with a resource ) ; 7 }) ; 8 9 module. exports = router ; routes/user.js 1 body { padding : 50 px ; 3 font : 1 px " Lucida Grande ", Helvetica, Arial, sans serif ; } 5 6 a { 7 color : #00B7FF ; 8 } 1 $ cd MySite && npm install $ npm start public/stylesheets/style.css Instalowanie zależności i uruchamianie aplikacji Dr inż. Stanisław Polak 7 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 8 Przedmiot: Aplikacje internetowe
MongoDB Ogólna charakterystyka Aplikacja 3 Nierelacyjna baza danych zorientowana dokumentowo Dobrze skalowana Szybka Nie posiada sztywnych schematów danych Podstawowe pojęcia Kolekcja odpowiednik tabeli w relacyjnej bazie danych Dokument odpowiednik wiersza w relacyjnej bazie danych Rysunek: Przykładowy dokument Dr inż. Stanisław Polak 9 Przedmiot: Aplikacje internetowe Model danych w MongoDB Referencje Aplikacja 3 Osadzane dokumenty Materiały dla studentów Informatyki WSZiB w Krakowie Dr inż. Stanisław Polak 30 Przedmiot: Aplikacje internetowe Instalowanie zależności Aplikacja 3 Tworzenie zawartości bazy danych Aplikacja 3 1 $ vi package. json $ npm install #i n s t a l o w a n i e z a l e ż no ś c i 1... " dependencies " : { 3... " monk " : "*" 5 } 6... package.json 1 $ mongo MongoDB shell version :. 6. 3 3 connecting to : test > use bazatestowa1 5 switched to db bazatestowa1 6 > db. datacollection. insert ({ " title " : " Express & Mongo " }) 7 > db. datacollection. insert ({ " title " : " Express " }) 8 > db. datacollection. find ( ) 9 { " _id " : ObjectId ( "5 f8bb757bade7ec7171 " ), " title " : " Express & Mongo " } 10 { " _id " : ObjectId ( "5 f8bd07bade7ec717 " ), " title " : " Express " } 11 > db. datacollection. find ({ " title " : " Express " }) 1 { " _id " : ObjectId ( "5 f8bd07bade7ec717 " ), " title " : " Express " } Dr inż. Stanisław Polak 31 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 3 Przedmiot: Aplikacje internetowe
Aplikacja 3 Źródła Modyfikacje Źródła I 1... var bodyparser = require ( body - parser ) ; 3 //Nowy kod var monk = require ( monk ) ; 5 var db = monk ( localhost :7017/ bazatestowa1 ) ; 6... 7 //Nowy kod 8 app. use ( function ( req, res, next ){ 9 req. db = db ; 10 next ( ) ; 11 }) ; 1 // I s t n i e j ą cy kod 13 app. use ( /, index ) ; 1 app. use ( / users, users ) ; 15... app.js 1... router. get ( / titles, function ( req, res ) { 3 var db = req. db ; var collection = db. get ( datacollection ) ; 5 collection. find ({},{}, function ( e, docs ){ 6 res. render ( titlelist, { 7 " titlelist " : docs 8 }) ; 9 }) ; 10 }) ; 11 1 module. exports = router ; routes/index.js MongoDB Inc. The MongoDB Manual. http://docs.mongodb.org/manual/. Joyent. Node.js Manual & Documentation. http://nodejs.org/api/. 1 extends layout. pug 3 block content h1 Tytu ł y 5 ul 6 each element in titlelist 7 li #{element. title} views/titlelist.pug Dr inż. Stanisław Polak 33 Przedmiot: Aplikacje internetowe Dr inż. Stanisław Polak 3 Przedmiot: Aplikacje internetowe