Mis on Node.js
Node.js on serveripoolne JavaScripti täitmiskeskkond (runtime), mis võimaldab käivitada JavaScripti väljaspool veebibrauserit. See tähendab, et JavaScripti saab kasutada mitte ainult kasutajaliidese loomiseks, vaid ka serverite, API-de ja rakendusloogika kirjutamiseks.

Oluline on rõhutada järgmist:
- Node.js ei ole programmeerimiskeel
- Node.js ei ole raamistik
- Programmeerimiskeel on JavaScript
- Node.js on keskkond, kus JavaScript serveris töötab
Tehniliselt koosneb Node.js mitmest komponendist:
- Google’i V8 JavaScripti mootor (kirjutatud C++ keeles)
libuvplatvormikiht asünkroonse I/O jaoks- Node.js-i enda tuumik, mis on suures osas JavaScriptis
See kombinatsioon võimaldab JavaScriptil suhelda operatsioonisüsteemi, võrgu ja failisüsteemiga.
Node.js arhitektuur ja tööpõhimõte
Node.js kasutab sündmuspõhist ja mitteblokeerivat arhitektuuri, mida tuntakse single-threaded event loop mudelina. See erineb oluliselt traditsioonilisest mitmelõimelisest serverimudelist.
Traditsiooniline mitmelõimeline server:
- iga päring saab oma lõime
- blokeerivad operatsioonid hoiavad lõime kinni
- suur koormus tähendab palju lõime ja suurt mälukulu
Node.js töötab teistmoodi:
- rakenduse loogika jookseb ühes põhilõimes
- sissetulevad päringud pannakse järjekorda
- event loop töötleb päringuid ükshaaval
- blokeerivad I/O-operatsioonid antakse üle taustalõimedele
- event loop jätkab teiste päringute teenindamist
Tulemuseks on väiksem ressursikasutus ja parem skaleeritavus I/O-mahukate rakenduste puhul.
Asünkroonne programmeerimine Node.js-is
Node.js eeldab asünkroonset programmeerimist. See tähendab, et aeglased operatsioonid ei peata kogu rakenduse tööd.
Praktikas kasutatakse:
- callback’e
- promise’e
- async/await süntaksit
Async/await muudab koodi loetavaks, kuid ei muuda seda sünkroonseks. Rakendus jääb mitteblokeerivaks, mis on Node.js-i tööpõhimõtte alus.
Kus ja milleks Node.js-i kasutatakse
Node.js sobib parimal juhul rakendustele kus on palju andmesuhtlust ning suhteliselt vähe raskeid arvutusi.
Levinumad kasutusvaldkonnad:
- REST API-d ja backend-teenused
- serveripõhised veebirakendused
- reaalajasüsteemid (chat, teavitused, socketid)
- IoT-lahendused
- arendustööriistad ja skriptid
Node.js ei ole hea valik CPU-mahukate arvutuste jaoks, kuid see ei ole ka selle eesmärk.
Node.js-i peamised eelised
- sama keel frontend’is ja backend’is
- väga suur npm pakettide valik
- hea jõudlus paljude spontentuaalsete päringute korral
- lihtne HTTP- ja API-põhine arendus
- sobivus pilve- ja mikroteenuste arhitektuuridele
Node.js-i piirangud ja riskid
- CPU-mahukad tööd võivad blokeerida event loop’i
- halb ahritektuur võib mõjutada kogu serverit
- nõuab arendajalt asünkroonse mõtteviisi mõistmist
Arenduskeskkonna ettevalmistus:
- Visual Studio code(ja extensionid)
- Prettier extension – vormindab koodi automaatselt ühtsesse stiili; parandab loetavust ega mõjuta programmi loogikat
- DotENV extension – lisab toe
.envfailide süntaksi esiletõstmiseks; kasulik siis, kui hakatakse kasutama keskkonnamuutujaid - JavaScript (ES6) code snippets – kiirendab JavaScripti kirjutamist; kasulik algajale, ei peida loogikat
- Database Client JDBC – võimaldab MariaDB andmebaasi vaadata, päringuid käivitada ja andmeid kontrollida otse VS Code’is
- Git & GitHub
- XAMPP (MariaDB)
Esimese Node.js programmi loomine
Node.js on JavaScripti fail seega lõin faili node01.js ja lisasin sinna alloleva koodi:
console.log("Tere maailm!");
console.log() väljastab Node.js-is teksti terminali.
Node.js programmi käivitamine
Programmi käivitamiseks kasutatakse Node.js käsurea käsku node. Terminalis käivita programm käsuga:
node node01.js
Node.js lubab JavaScripti faili käivitada ka ilma .js laiendit kirjutamata:
node node01
Õppimise algfaasis kasutan täisfailinime, et failid oleksid selgelt eristatavad.
Meeldetuletus JavaScriptist
Enne Node.js rakenduste arendamisega edasi liikumist kordan üle mõned JavaScripti konstruktsioonid, mida Node.js koodis kasutatakse pidevalt. Vastasel juhul muutub Node.js kood raskesti loetavaks ja ebamugavaks kirjutada.
Noolefunktsioonid (Arrow functions)
Noolefunktsioonid on lühem ja tänapäevasem viis funktsioonide kirjutamiseks. Node.js koodis kasutatakse neid sageli callback’ide, abifunktsioonide ja lihtsa loogika puhul.
const tervitus = (nimi) => {
return "Tere " + nimi;
};
Üherealise funktsiooni lühivorm:
const tervitus = nimi => "Tere " + nimi;
Noolefunktsioonid on levinud, kuna süntaks on lühem ja sobib hästi väikeste funktsioonide jaoks.
Teksti vormindamine (template literals)
Node.js rakendustes kasutatakse sageli dünaamilisi tekste, näiteks logisid ja veateateid. Template literal’id muudavad sellise teksti koostamise selgemaks.
const nimi = "Juhan";
console.log(`Tere ${nimi}!`);
Template literal’id on loetavamad kui stringide ühendamine + märgiga ning võimaldavad kirjutada ka mitmerealisi stringe.
Objekti ja massiivi destruktureerimine
Node.js koodis töötatakse pidevalt objektide ja konfiguratsioonidega. Destruktureerimine võimaldab vajalikud väärtused objektist või massiivist otse kätte saada.
const config = {
host: "localhost",
user: "root",
password: "secret"
};
const { host, user } = config;
Massiivide puhul:
const [esimene, teine] = ["a", "b", "c"];
Destruktureerimist kasutan sageli configides, functionites, paramites ja vastusobjektide töötlemisel.
Vaikimisi väärtused (default values)
Node.js tuleb arvestada, et alati ei pruugi kõik väärtused olemas olla. Selleks kasutame vaikimisi väärtusi et vältida undefined olukordi.
const tervitus = (nimi = "külaline") => {
console.log(`Tere ${nimi}`);
};
Asünkroonne süntaks (async ja await)
Node.js-is on failide lugemine, andmebaasipäringud ja võrgutöö asünkroonsed.
const loeFail = async () => {
const sisu = await fs.promises.readFile("test.txt", "utf8");
console.log(sisu);
};
Süntaks peaks olema arusaadav ka siis, kui teemat veel sügavuti ei käsitleta.
Vigade käsitlemine (try...catch)
Vigade pyydmis syntax:
try {
teeMidagi();
} catch (error) {
console.error(error.message);
}

