Hey, w ostatnim wpisie pokazałem jak zainstalować NodeJS, jednak nie pokazałem jak można wykorzystać go do stworzenia swoich, legendarnych aplikacji.

Użycie modułów przedstawię na przykładzie prostej aplikacji do zarządzania ulubionymi cytatami(jeśli któs je ma 🙂 ).

A więc zacznijmy.

Początek

Tworzymy katalog, w którym będziemy działać.

mkdir cytaty

Ja go nazwałem cytaty, choć możecie je nazwać jak chcecie.

Następnie wchodzimy do niego

cd cytaty

Dalej jest czas na zainicjowanie projektu NodeJS

W tym celu używamy komendy npm init i klikamy ciągle enter

npm init

W naszym katalogu został utworzony plik package.json, który zawieda dane dotyczące naszego programuA tak może wyglądać przykładowa zawartość naszego pliku :

{
  "name": "cytaty",
  "version": "1.0.0",
  "description": "Aplikacja o cytatach",
  "main": "app/app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/legendemil/cytaty.git"
  },
  "author": "Emil Pausz",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/legendemil/cytaty/issues"
  },
  "homepage": "https://github.com/legendemil/cytaty#readme"
}

Nie ma tu nic dziwnego. Znaczenie poszczególnych opcji:

-name – oznacza nazwę naszego modułu(tu określamy jakiej nazwy będa używać inni aby korzystać z naszego modułu)

-version – wersja modułu

-description – opisuje funkcjonalność naszego modułu

-main – określa plik, który odpowiada za wyeksportowanie naszego modułu

-scripts – tutaj możemy umieszczać polecenia powłoki, jakie będziemy często wykonywać(o tym za chwilę)

-repository – okresla nasze repozytorium git

-author – chyba wiadomo 🙂

-license – typ licencji naszego modułu

Stworzenie strony

Dalej stworzymy podstawową stronę html, która będzie wyświetlać naszą aplikację. Tworzymy plik index.html i otwieramy w dowolnym edytorze tekstowym(może być notatnik, ale bardzo gorąco polecam zapoznać się z  Sublime Text lub Atom).

Przykładowa zawartość index.html

<!DOCTYPE html>
<html lang='pl'>
<head>

    <meta charset="UTF-8">
    <title>Najlepsze cytaty</title>

    <!-- czcionka Roboto z google fonts -->
    <link href='https://fonts.googleapis.com/css?family=Roboto:400,300&subset=latin,latin-ext' rel='stylesheet' type='text/css'>

    <!-- załadowanie styli CSS -->
    <link rel="stylesheet" type="text/css" href="css/main.css">

</head>
<body>
    
    <!-- header -->
    <header>
        <div class="wrapper">
            <h3>Moje ulubione cytaty</h3>
        </div>
    </header>

    <!-- creating quote form -->
    <section>
        <div class="wrapper">
            <h3>Dodaj cytat</h3>
            <form id='addForm' class='center'>

                <textarea name='quote' id='quote'></textarea> <br>

                <label for='author'>Autor</label>
                <input type='text' name='author' id='author'/>

                <input type='submit' name='submit' value='Dodaj'/>
                <div style='clear: both;'></div>
            </form>
        </div>
    </section>
    
    <!-- displaying quotes -->
    <main>
        <div class="wrapper">
            <!-- contains quotes -->
            <div id="quotesContainer">
                <!-- list of quotes -->
                 <div class='quote center' id='no-quotes-info'>
                    Nie masz jeszcze ulubionych cytatów
                  </div>
            </div>
        </div>
    </main>
    
    <!-- site footer -->
    <footer>
        <div class="wrapper">
            Created by Emil Pausz
        </div>
    </footer>

</body>
</html>

Dodanie styli CSS(make it beautiful)

Teraz nastał czas na stworzenie arkusza styli CSS. Tworzenie CSS to jedna z przyjemniejszych czynności. Aby jeszcze bardziej upięknić piękno tworzenia CSS wymyślono preprocesory CSS. Jednak tym razem wykorzystam czysty CSS. W przyszłości postaram się stworzyć wpis o tej technologii CSS. Dla zainteresowanych(StylusSASS)

Tworzymy plik main.css w folderze css i dodajemy poniższą treść

/*
    dark-grey #263238
    light-grey #eceff1
*/

* {
    font-family: 'Roboto', sans-serif;
    color: #263238;
}

.wrapper {
    width: 1440px;
    max-width: 80%;
    margin: 0 auto;
}

.center{
    width: 90%;
    max-width: 500px;
    margin: 0 auto;
}

/* 
    header styles
 */

header {    
    text-align: left;
}

/*
    section styles
*/

section h3 {
    text-align: center;
}

section form {
    color: #263238;
}

#addForm textarea {
    display:  block;
    font-size: 1.2rem;
    font-weight: 100;
    width: 100%;
    background-color: #eceff1;
    color: #263238;
    outline: none;
    border: none;
    resize: none;
    padding: 1.2rem;
    box-sizing: border-box;
}

#addForm #author {
    padding: .4rem;
    font-size: .8rem;
}

#addForm label {
    font-weight: 100;
    font-size: 1.3rem;
}

#addForm #author, #addForm label {
    font-weight: 100;
}

#addForm input[type='submit']{
    border: none;
    padding: .5rem 1rem;
    background-color: #eceff1;
    color: #263238;
    float: right;
}

/*
    main styles
*/

main {
    margin-top: 3rem;
    margin-bottom: 3rem;
}

.quote {
    margin-top: 1rem;
    background-color: #eee ;
    padding: 1rem .4rem;
    line-height: 150%;
}

.quote button.deleteQuoteBtn {
    float: right;
    border: none;
    outline: none;
    padding: .3rem .6rem;
    background-color: white;
    color: #263238;
    cursor: pointer;
}

/*
    footer styles
*/
footer {
    text-align: center;
}

Po dodaniu powyższych stylów strona będzie wyglądać następująco.

cytaty1

Plik main.css zawiera ponadto style dla nowo stworzonych cytatów, których na razie nie ma.

 

Czas na Javascript!

Przygodę z JS w tym projekcie zaczniemy od stworzenia pliku app.js w folderze app. Plik app.js będzie zawierał całą logikę naszej aplikacji. Będzie on jednak korzystać z innych modułów Javascript. Aplikację oprę na bibliotece jQuery, który w bardzo prosty sposób umożliwia manipulację DOM-em (Document Object Model).

NodeJS udostępnia polecenie npm install <nazwa_modułu>, za pomocą którego możemy instalować moduły NodeJS. Przełącznik -S sprawi, że moduł zostanie zainstalowany lokalnie w obecnej aplikacji, natomiast przełącznik -g instaluje moduł globalnie.

Ponadto przełącznik -S:

-tworzy katalog node_modules, gdzie znajdują się zainstalowane lokalnie moduły,

-dodaje do pliku package.json(aktualizuje obiekt dependencies lub devDependencies) informację, że nowy moduł został zainstalowany.

 

A więc do dzieła, zainstalujmy jQuery.

npm install -S jquery

Na systemach Linux, MacOS komenda ta może wymagać dodanie na początku sudo.

sudo npm install -S jquery

Jak możemy zobaczyć w naszym folderze stworzył się folder node_modules, a w nim folder jquery.

Teraz możemy użyć modułu w naszej aplikacji, używając funkcji require(nazwa_modułu).

// app/app.js
var $ = require('jquery');

Do zmiennej $ przypisujemy moduł jQuery. Jednak gdybyśmy dodali ten skrypt do pliku index.html i włączyli stronę otrzymalibyśmy błąd, gdyż funkcja require() nie jest obsługiwana przez przeglądarki, lecz tylko przez NodeJS.

reference_error

Aby pozbyć się powyższego błędu musimy użyć innego modułu npm, Browserify. Pozwala on korzystać z modułów npm w przeglądarce. Ponadto nie musimy zaśmiecać pliku html listą tagów typu script[src=’biblioteka.js’], gdyż browserify buduje ze wszystkich zależności(jakich użyliśmy) jeden plik.

A więc do dzieła!

Instalujemy browserify przez npm install -S, jeśli chcemy tylko dla tego projektu

npm install -S browserify

lub jeśli często będziemy korzystać globalnie, dla całego systemu

npm install -g browserify

 

Następnie tworzymy plik bundle.js, który będzie zawierał nasz wynikowy kod wykonujemy komendę w wierszu poleceń

browserify app/app.js -o bundle.js

Po wykonaniu tej komendy do pliku bundle.js zostanie zapisany po przetworzeniu kod z pliku app.js.

Następnie dołączamy nasz plik bundle.js do pliku index.html, tuż przed zamknięciem znacznika body

        <!-- reszta część kodu -->   
        <!-- bundle js -->
    <script src='bundle.js'></script>
</body>
</html>

Teraz w konsoli naszej pzeglądarki nie powinno być żadnego błędu.

 

Jednak po zapisaniu pliku app.js, plik bundle.js pozostaje bez zmian, musimy ciągle przechodzić do terminala i wpisywać komendę

browserify app/app.js -o bundle.js

Aby zmiany na bieżąco były zapisywane należy użyć modułu watchify. Instalacja przebiega analogiczne jak instalacja browserify

npm install -S watchify //instaluje lokalnie

lub

npm install -g watchify //instaluje globalnie

Następnie wydajemy polecenie

watchify app/app.js -o bundle.js -v

Od tej pory każda zmiana w pliku app.js będzie automatycznie zapisywana do pliku bundle.js. Przełącznik -v odpowiada za wyświetlanie na bieżąco w terminalu ile czasu zajęło przetworzenie pliku.

Livereload

Mimo to, że zmiany są zapisane na bieżąco wciąż trzeba odświeżać okno przeglądarki, by zobaczyć zmiany. Aby strona automatycznie się odświeżała po każdej zmianie, należy użyć serwer livereload.

W tym projekcie użyje prostego, lecz skutecznego LiveServera.

Instalujemy go zgodnie z instruckją zamieszczoną na githubie tego projektu

npm install -g live-server

Następnie tworzymy plik live-reload.js, który będzie odpowiadał za nasz lokalny serwer, uruchomiony na porcie 8080

var liveServer = require("live-server");

var params = {
    port: 8080, // Set the server port. Defaults to 8080.
    open: true, // When false, it won't load your browser by default.
    file: "index.html", // When set, serve this file for every 404 (useful for single-page applications)
    mount: [['/components', './node_modules']], // Mount a directory to a route.
    logLevel: 2 // 0 = errors only, 1 = some, 2 = lots
};
liveServer.start(params);

Teraz czas go uruchomić. Aby to zrobić wydajemy komendę

node live-reload.js // uruchamiamy serwer
watchify app/app.js -o bundle.js -v // watch mode

Po wydaniu tej komendy powinna otworzyć się przeglądarka na adresie http://127.0.0.1:8080/, gdzie będzie się wyświetlać nasza strona. Teraz po każdej zmianie pliku, strona będzie się automatycznie odświeżać.

Awesome!

Jednak gdy zrobimy błąd w naszej aplikacji, to nasza konsola wskaże jako miejsce błędu linijkę kodu w pliku bundle.js, a nie tam gdzie tak naprawdę został popełniony. Nie jest to najlepsze rozwiązanie :/. Jednak z pomocą przychodzą sourcemapy. Umożliwiają one naprawienie tego błędu i miejsce wystąpienia błędu będzie wskazywane prawidłowo.

Za generowanie sourcemapów w browserify odpowiada flaga –debug

browserify --debug app/app.js -o bundle.map.js //lub
watchify --debug app/app.js -o bundle.map.js

To spowoduje utworzenie pliku bundle.map.js, który będzie zajmował więcej miejsca na dysku niż plik bundle.js.  Po dodaniu pliku bundle.map.js do strony konsola przeglądarki będzie prawidłowo wskazywać, gdzie popełniliśmy błąd. Plik z sourcemapami powinien być używany tylko w środowisku deweloperskim, gdyż zawiera informacje, które nie są potrzebne w środowisku produkcyjnym.

Do usuwania sourcemapów z pliku służy moduł exorcist.

npm install -g exorcist
browserify app/app.js --debug | exorcist bundle.map.js > bundle.map.js

Natomiast do minifikacji plików(sprawienia aby zajmowały mniej) służy minifyify. 

npm install -S minifyify

Aby z niego skorzystać, należy wydać polecenie

browserify app/app.js --debug -d -p [ minifyify --map bundle.map.js --output bundle.map.js ] > bundle.js

Ciąg dalszy nastąpi..

Myślę, że pora zakończyć ten wpis. W następnej części aplikacja o cytatach zostanie dokończona. Mam nadzieję, że post się podobał.