Főoldal

"Mérnököt a mérnöktől"

A Schönherz Bázis összeköti az állást kereső és állást kínáló mérnököket.

CV küldés

Küldj önéletrajzot! Gyorsan, egyszerűen.
Megjegyzésbe írd be a pozíció nevét.
CV küldés

Iratkozz fel hírlevelünkre!

Hírek

Node.js teljesen kezdőknek
Node.js teljesen kezdőknek
Nem mondanám, hogy hiány van Node.js tutorialokból, tele van velük az internet, de a legtöbb valamilyen specifikus dologra fókuszál (pl. use cases), amikre csak akkor van szükséged, ha már telepítetted, beállítottad a Node-ot.

Éppen ezért újra és újra szembejönnek velem a “letöltöttem a Node-ot, és most hogyan tovább?” típusú kommentek. Ennek a tutorialnak az a célja, hogy az legelejétől végigvezessen az alapokon.
 
Mi is a Node.js? Rengeteg félreértés adódik abból, hogy a kezdők félreértik mi is maga a Node.js, mire jó, a nodejs.org-on található leírás pedig egyáltalán nem segít eloszlatni a ködöt.
 
Azt kell megérteni, hogy a Node nem webszerver, saját maga nem csinál semmit. Nem úgy működik, mint pl. az Apache, nincs config fájl, amivel a HTML fájlokra mutatsz. Ha HTTP szervert szeretnél, akkor meg kell írnod egy HTTP szervert. A Node.js csak egy újabb mód arra, hogy futtasd a programodat.
 
 
A Node installálása
 
Ez nagyon egyszerű. Ha Mac vagy Windows oprendszert használsz, akkor a download oldalon megtalálhatod a telepítéshez szükséges fájlokat.
 

Telepítettem, és most?
 
Miután feltelepítetted a Node-ot a gépedre, kétféleképpen használhatod a “node” parancsot. Egyrészt argumentumok nélkül, ez egy interaktív shell-t fog megnyitni, ahol futtathatod a JavaScript kódod.
 
Egy példa:
 
$ node
 
> console.log('Hello World')
 
Hello World
 
undefined
 


 
 
A fenti példában a “console.log” ('Hello World')” sort írtam a terminálba, majd nyomtam egy entert.   Ekkor a Node futtatja a kódot, és láthatjuk a megadott üzenetünket. Az “undefined”-ot azért írja ki, mert minden parancs visszatérési értékét kiírja, és a console.log nem ad semmilyen értéket.
 
Ez volt az egyik módszer a futtatáshoz, a másik, hogy megadunk neki egy JavaScript fájlt. Szinte mindig ezt fogod használni.

A példakód:
 
hello.js
 
console.log('Hello World');
 
$ node hello.js
 
Hello World

 


Ebben a példában átmozgattam a console.log kiíratását (Hello World) egy fájlba, majd ezt adtam meg a node parancs argumentumának, így a Node futtatja a JavaScriptem az adott fájlon és kiírja, az üzenetünket: 'Hello World'.
 
 
Legyünk hasznosak! - Fájl I/O
 
Jó móka JavaScripteket futtatni, de sok haszna nincsen. Ezért a Node.js tartalmaz egy csomó könyvtárat, melyekkel igazán király, hasznos dolgokat csinálhatunk. Első példánkban megnyitok egy log fájlt és elemezem a tartalmát.
 
 
example_log.txt - az adatokat tartalmazó fájl

 
2013-08-09T13:50:33.166Z A 2
 
2013-08-09T13:51:33.166Z B 1
 
2013-08-09T13:52:33.166Z C 6
 
2013-08-09T13:53:33.166Z B 8
 
2013-08-09T13:54:33.166Z B 5

 
 
Hogy a fájl adatai mit jelentenek az teljesen mindegy, a lényeg, hogy minden sorban egy dátumot és egy ahhoz tartozó értéket találunk. Azt szeretném elérni, hogy minden betűnél megjelenjen a hozzá tartozó, összesített érték. Ehhez először is be kell olvasnom az adatokat:
 
 
my_parser.js
 

//   fs (filesystem) modul betöltése
var fs = require('fs');
 
// Adatok memóriába olvasása
 
fs.readFile('example_log.txt', function (err, logData) {
 
  // ha valami gond van a throw-al leállítjuk a futást és kiíratjuk
// a kivételt
 

  if (err) throw err;
 
// logData egy Buffer, konvertáljuk string-é
 
  var text = logData.toString();
 
});
 

 
Szerencsénkre a Node.js pofonegyszerűvé teszi a I/O-t, köszönhető ez a beépített filesystem (fs) modulnak, mely tartalmaz egy readFile függvényt. Ez utóbbinak egy fájlt és egy visszahívást (általában függvényt), callback-et kell megadnunk, mely akkor lép életbe, miután a fájl olvasása befejeződött. Az adatok Buffer formájában érkeznek, ezeket érdemes string-é alakítani a toString() függvénnyel.
 
Beolvastuk, stringünk is van, elemezzük az adatokat. Ez a része ugyanúgy működik, mint a JavaScript-ben, így nem megyek bele a részletekbe.
 
my_parser.js
 

//   fs (filesystem) modul betöltése
var fs = require('fs');
 
 // Adatok memóriába olvasása
fs.readFile('example_log.txt', function (err, logData) {
 
// ha valami gond van a a throw-al leállítjuk a futást és kiíratjuk
// a kivételt
 

  if (err) throw err;
 
// logData egy Buffer, konvertáljuk string-é
 
  var text = logData.toString();
 
 
var results = {};
 
// Fájl sorokra tördelése
  var lines = text.split('\n');

 
 
lines.forEach(function(line) {
 
    var parts = line.split(' ');
 
    var letter = parts[1];
 
    var count = parseInt(parts[2]);
 
if(!results[letter]) {
 
      results[letter] = 0;
 
    }
 
results[letter]
+= parseInt(count);
 
  });
 
console.
log(results);
 
  // { A: 2, B: 14, C: 6 }
 
});

 
 

Ha ezt a fájlt adjuk meg a node argumentumának, akkor az kiírja nekünk az eredményt, majd kilép.
 
$ node my_parser.js
 
{ A: 2, B: 14, C: 6 }

 

 
Rengetegszer használom a node.js-t ilyen helyzetekben, sokkal hatékonyabb, mint ugyanezt megcsinálni bash scriptekkel.
 
 
Az Aszinkronikus callback
 
Ahogy az már az előző példában is látszott, tipikusan aszinkronikus (asynchronous) callback-eket használunk. Tulajdonképpen megmondjuk neki mit csináljon, és ha végzett, akkor hívja meg a függvényünket. Azért működik így, mert a Node egyszálú: amíg a callback-re vársz, a Node csinálhat mást, ahelyett, hogy blokkolnia kéne a feltétel teljesüléséig.
 
Ez utóbbi különösen webszerverek esetén fontos. Ma már elég gyakori az appoknál, hogy adatbázisokhoz férünk hozzá. Amíg arra várunk, hogy az adatbázis “válaszoljon”, értékeket adjon, addig a Node nyugodtan csinálhat mást, pl még több kérést, parancsot teljesíthet. Miért jó ez? Mert elég “olcsón” megússzuk a több ezer egyidejű kapcsolat kezelését, legalábbis jobban járunk, mintha minden egyes kapcsolathoz új szálat rendelnénk.
 
 
Még mindig hasznosak vagyunk - HTTP Szerver
 
A Node nem csinál semmit csak úgy magától, de az egyik beépített modullal elég egyszerűen alkothatunk “fapados” HTTP szervert, a példa:
 
 
my_web_server.js


var http = require('http');

 
http.createServer(function (req, res) {
 
  res.writeHead(200, {'Content-Type': 'text/plain'});
 
  res.end('Hello World\n');
 
}).listen(8080);
 
 
 console.log('Server running on port 8080.');
 
 
Nem véletlenül használtam a fapados jelzőt, ez tényleg csak az alap. Ez a példa konkrétan azt csinálja, hogy bármilyen kérésre a Hello World-t adja vissza, de megnézheted a böngésződben:
http://localhost:8080
 
Ott a szöveg, igaz?
 
 
$ node my_web_server.js
 

 
 
Közben észrevehettünk valamit: a Node.js már nem létezik, ez azért van, mert egy szervert hoztunk létre, és a Node.js egészen addig fog futni, amíg le nem lövöd, kézzel...
 
Márpedig, ha egy működő rendes webszervert akarsz, akkor igenis meg kell nézned mi volt a bejövő kérés, be kell olvasnod a fájlokat és visszaküldeni az eredményt. A jó hír, hogy ezt már rég megcsinálták helyetted.
 
És már megint hasznosak vagyunk – Express
 
Az Express egy környezet, amivel nagyon egyszerűen hozhatunk létre honlapokat. Első lépésként nem árt telepíteni. A node parancs mellett az “npm” parancsot is használhatod, ezzel megnyílik az ajtó a közösség által fejlesztett modulok felé, ezek közül az egyik az Express.
 
 
$ cd /my/app/location
 
$ npm install express
 
 

A telepített modul a node_modules mappába fog kerülni, ezután pedig úgy használhatod, mint bármelyik másik beépített modult. Hozzunk létre egy fájlszervert:
 
my_static_file_server.js


var express = require('express'),
 
    app
= express();
 
  
app.use(express.
static(__dirname + '/public'));
 
 app.listen(
8080);

 
$ node my_static_file_server.js

 
 
Kész is, bármi, ami a /public mappában van, most már lekérhető a böngésződdel, HTML, képek, gyakorlatilag bármi. Tehát, ha van egy “my_imaga.png” nevű kép a public mappában, akkor ezt elérheted a böngésződből a  http://localhost:8080/my_image.png beírásával.
 
Persze az Expresst sok minden másra is lehet használni, de ezeknek a lehetőségeknek majd utánanézel ahogy fejlődsz.
 
 
NPM
Ezt a témát már érintettük az előző fejezetben valamilyen szinten, de szeretném kihangsúlyozni mennyire fontos is az NPM a normál Node.js fejlesztéseknél. Több ezer modul létezik, melyek jó eséllyel megoldják minden bajod, így mindig ellenőrizd az npm-et mielőtt elkezdesz egy problémát (újra) megoldani, felesleges újra feltalálni a spanyol viaszt.
 
Egy tipikus Node.js app nem ritkán több tucat modult használ. Az előző példában kézzel, saját magunk telepítettük az Expresst, ami nem túl jó ötlet, ha tele vagyunk függésekkel, ezt megoldja a package.json fájl :
 
 
package.json

{
 
  "name" : "MyStaticServer",
 
  "version" : "0.0.1",
 
  "dependencies" : {
 
    "express" : "3.3.x"
 
  }
 
}
 

 
 
Mit tartalmaz a package.json? Az alkalmazás összefoglalója, a példában nagyjából a minimumot látjuk. A függőség rész tartalmazza a használt (telepíteni kívánt) modulokat és azok verzióit. Jelen esetben pl. az Express 3.3 bármilyen verziója elfogadott. Ebben a részben annyi modult adsz meg amennyit csak akarsz.
Így nem kell minden egyes modult egyesével telepíteni, erre az egy parancsra van szükségünk, és már végeztünk is.
 
 
$ npm install

 
 
Ha ezt a parancsot futtatjuk, az npm az adott könyvtárban megkeresi a package.json fájlt, ha megtalálja akkor minden listázott modult telepít.
 
A kód elrendezése
Eddig csak olyan kódokat használtunk, amelyek egy fájlban voltak elhelyezve, ez a legtöbb alkalmazásnál fenntarthatatlan, több helyen lesznek különböző kódrészletek. Azt azért kiemelném, hogy ez nem  a Rails, semminek nincs kitüntetett helye, mindent oda pakolsz ahova csak akarsz.
 
Nézzünk rá újra az elemző kódra, ha kivesszük magát az elemző részt, akkor sokkal átláthatóbb lesz a kód.
 
parser.js
 
 
// Parser
 

var Parser = function() {
 
};
 
// megadott .txt elemzése
 

Parser.prototype.parse = function(text) {
 
 

var results = {};
 
 
// sorokra tördelés
 
 
var lines = text.split('\n');
 
lines.
forEach(function(line) {
 
   
var parts = line.split(' ');
 
   
var letter = parts[1];
 
 
   var count = parseInt(parts[2]);
 
   
 

if(!results[letter]) {
 
      results[letter]
= 0;
 
    }
 
results[letter]
+= parseInt(count);
 
  });
 
 

return results;
 
};
 
// Exportálás a modulból
 
module.exports
= Parser;
 

 
Mi történt?  Egy új fáljt csináltam az elemzéshez, ez csak egy sima JavaScript, rengetegféleképpen meg lehetne ezt oldani, azért új JavaScript objektumot tettem bele, mert így könnyű a tesztelés.
 
Az egész legfontosabb része a “module.exports”, ez mondja meg a Node-nak, hogy mit exportálok ebből a fájlból.
 
Ezután még azt kell megnéznünk, hogyan lehet ezt a fájlt importálni az új Parser objektumunkkal.
 
 
my_parser.js


// Szükség van a parser.js fájlra
 

var Parser = require('./parser');
 
//fs (filesystem) modul behívása
 

var fs = require('fs');
 
// Memóriába olvasás
 
fs.readFile(
'example_log.txt', function (err, logData) {
 
// Hiba esetén kilép
 
 
if (err) throw err;
 
 
// Bufferből string
 
 
var text = logData.toString();
 
 
// Create an instance of the Parser object.
 
 
var parser = new Parser();
 
 
// parse függvény meghívása
 
  console
.log(parser.parse(text));
 
  // { A: 2, B: 14, C: 6 }
 
});
 

 
 
A fájlokat és a modulok behívása megegyezik, annyi a különbség, hogy most meg kell adni a fájl elérési útvonalát, a .js kiterjesztést nem is kell hozzáírni,ez az alapértelmezett.
 
  
Összefoglalás

Remélem hasznos volt a tutorial, és sikerült kitöltenem a letöltés és az első kód írása közti űrt. A Node.js nagyon rugalmas és erős technológia, amit rengeteg probléma megoldására használhatunk.
 
Mindenkit emlékeztetnék arra, hogy a Node.js határait a saját képzelőerőnk szabja csak meg. A beépített könyvtárak úgy vannak megadva, hogy biztosítsák a megfelelő építőkockákat, a modulokkal pedig hihetetlenül gyorsan lehet komplex, bonyolult alkalmazásokat írni.
 
Írta: Brandon Cannaday

(Forrás)