FS, JS könyvtárak és Node.js modulok, NPM, nodemon

Modulok


A JavaScript (mint nyelv) már hosszú ideje támogatja a modulokat. Rendkívül sok előny származik a modulok használatából, melyek közül leginkább kiemelendőek az alábbiak: karbantarthatóság, névtér, újrafelhasználhatóság [19]. A modulok célja az, hogy az egyes különálló futattható fájlokban ne kelljen ugyanazon kívánt funkciók eléréséhez újra deklarálni ugyanazt az utasítás sorozatot, hanem megegyezés szerint egy fájlban deklaráljuk az adott funkciót és mégis hozzáférhetőek legyenek más fájlok számára pusztán a megfelelő kulcsszavak használatával. Annak ellenére, hogy a JavaScript az ES5 idején (és előtte) nem rendelkezett beépített modulokkal, az idő előrehaladtával a nyelvet használó és fejlesztő közösség által jelentősen letisztult a teljes modulrendszer használata, melyet megörökölt az ES6:

• Minden egyes modul egy külön fájlban elhelyezett kódrészlet, mely végrehajtódik amint betöltődik.

• Ezen kódrészlet tartalmazhat változó és függvény deklarációkat. Alapértelmezetten ezek a modulon belül lokális hatókörrel rendelkeznek, azaz az egységbezárás koncepcióját valósítják meg.

• Ezeket a modulokat lehet exportálni és importálni. Az előbbiből következik az a dolog, hogy egy modul több másik modult is importálhat a modulok hivatkozásával, mely történhet útvonalak megadásával (relatív vagy abszolút) vagy a nevén nevezve. A hivatkozást követően történik a modul példányosítása, mely azinkron módon történik.

• A modulok singleton-ok. Akárhányszor betölthetünk egy modult, ugyanúgy egyetlen példánya fog létezni.

A koncepció megértéséhez vizsgáljuk meg a lenti példát! Definiálva van egy Felhasznalo osztály az innenexportalunk.js fájlban, nev és eletkor tulajdonságokkal Ezen felül a nevkiir és az eletkorkiir függvények. A célunk az, hogy exportáljuk a felhasznalo osztályt az innenimportalunk.js fájlba. Ezt kétféleképpen tehetjük meg: export default vagy export. Szintaxisa szerint az első megvalósítási lehetőség úgy néz ki, hogy használjuk a felhasznalo osztály deklarációja elé az export default kulcsszót (alapértelmezetten csak egy dolgot lehet exportálni egy fájlból, legyen ez az osztály), a függvények deklarációja elé pedig az export kulcsszót. Egy másik megközelítése a dolgok exportálásánal a module.exports kulcsszó használatán alapszik. Objektumot deklaráljunk literálként uzenet névvel, hozzunk létre neki tulajdonságot szoveg névvel és adjuk át neki a "Az exportálás sikeresen megtörtént!" stringet. Ezt az objektumot úgy exportálhatjuk, hogy értékül adjuk a module.exports-nak. Az innenimportalunk.js fájlban úgy tehetjük elérhetővé az előzőleg alapértelmezetten kiexportált osztályt, hogy az import kulcsszó után írjuk az osztály elnevezését (Felhasznalo), azt követően a from kulcsszót és végül az importálás (relatív) útvonalát ''-be foglalva. Végezetül lepéldányosítjuk az osztályt (mint mint felhasznalo nevezetű objektum) Péter névvel és 19 életkorral. Az exportált és importált osztálynévnek nem kell feltétlenül megegyeznie, viszont egy fájlon belül konvenció szerint azonos legyen az importálási név. Ez vonatkozik a példányosításra is. A nem alapértelmezetten exportált dolgok importálásához {}-ba foglalva meghívhatjuk őket a nevüket beleírva. Ha más néven szeretnénk meghívni, mellé írjuk az as alias kulcsszavakat, ahol az alias a tetszés szerinti elnevezés. A module.exports-szerint exportált objektumot a require() kulcsszó használatával tehetjük meg. Az argumentumába írjuk a fájl relatív útvonalát '' közé végül az importált értéket (mint objektum) az eztkapjuk nevű változóba.

//  innenexportalunk.js

export default class Felhasznalo {
	constructor(nev, eletkor){
		this.nev = nev;
		this.eletkor = ev;
	}
};

export const nevkiir(felhasznalo) => {
	console.log(`A felhasználó neve: ${felhasznalo.nev}`);
};

export const eletkorkiir(felhasznalo) => {
	console.log(`A felhasználó életkora: ${felhasznalo.eletkor}`);
};

let uzenet = {};

uzenet.szoveg = "Az exportálás sikeresen megtörtént!";

module.exports = uzenet;

//  innenimportalunk.js

import Felhasznalo, {nevkiir, eletkorkiir} from './innenexportalunk.js';

const eztkapjuk = require('./innenexportalunk.js');

const uzenetkiir() => {
  console.log(eztkapjuk.uzenet);
};

uzenetkiir();  
//  Az exportálás sikeresen megtörtént!

const felhasznalo = new Felhasznalo('Péter', 19);

console.log(felhasznalo);
nevkiir(felhasznalo);  
//  A felhasználó neve: Péter
eletkorkiir(felhasznalo);  
//  A felhasználó életkora: 19   

NPM


Az NPM a Node Package Manager szavak rövidítése, ami elsősorban egy online platformot takar (https://npmjs.com), másrészt egy parancssoron elérhető szolgáltatást [15]. Az elsőt arra lehet használni, hogy JavaScript nyelven írt (a CommonJS specifikációit követve) modulodat megoszthasd teljesen ingyen másokkal. A kereső feltületén keresztül a megfelelő kulcsszavakat megadva kidob egy a keresés feltételeinek megfelelő találati listát azokból a könyvtárakból, amiket mások, vagy te magad már feltöltöttél. Mivel JavaScriptben íródtak, nagy a valószínűsége, hogy mind szerveren, a parancssoron, vagy akár a böngészőn le tudnak futni. A feltelepített modulokat a require('modulnev') paranccsal tudjuk elérni. Ezzel a paranccsal egy objektumot kapunk vissza, melyet egy tetszés szerinti változóhoz rendelhetünk. Az NPM parancssori változata egyfajta kiegészítője az online grafikus felületnek. Telepítésének előfeltétele a NodeJs (valamelyik verziója). Magát a telepítést az npm install npm paranccsal tehető meg. Többek között arra használják, hogy telepíthessünk vagy törölhessünk modulokat. A telepítés során megszabhatjuk, hogy melyik verziót szeretnénk telepíteni, ha el szeretnénk kerülni a későbbiekben az inkompatibilitást. A telepített modulok neveit és verziójukat nyilván tarthatjuk az úgynevezett package.json fájlban, amit mi magunk is létrehozhatunk, vagy egy template projekt közben automatikusan legenerálódik. Az npm install paranccsal a package.JSON által nyilván tartott összes modul feltelepül a node_modules könyvtárban. Egy modul gyakran sok más modul előfeltétele is lehet. Emiatt viszont nem kell aggódni, az NPM elvégzi a számunkra a piszkos munkát azzal, hogy megkeresi és telepíti az összes szükséges modult.

Nodemon


Amikor az éppen futó kódunkon végzünk el változtatásokat, a mentést követően nem lépnek érvénybe ezen változtatások. Minden egyes alkalommal újra kell indítani a teljes programot. Komplexebb applikációk esetén már egy csomó időt elvesz a fejlesztőktől. A probléma megoldására alkották meg a Nodemon modult. Visszatérve a projekt_neve mappához, egészítsük ki a fejlesztői környezetünket a modul feltelepítésével az npm install -g nodemon paranccsal. A telepítés ezúttal globális lesz ami azt jelenti, hogy minden egyes projektnél elérhető lesz ez a funkció akár telepítve volt előtte lokálisan, akár nem. A telepítés után indítsuk újra a szervert ezúttal a nodemon server.js paranccsal. Eszközöljünk rajta némi változtatést a szerveren, mentsük el és nézzük meg mi történik!
> package name: (projekt_neve)

FS


A FileSystem, röviden FS a NodeJs olyan beépített modulja, melynek segítségével különböző fájlműveletek hajthatóak végre. A modul minden egyes metódusának deklarálva van a szinkron és aszinkron változata. Az aszinkron változat egy függvény paraméterrel többet vár, aminek van a hiba és a teljesített ága. Az aszinkron verzió implementálást gyakrabban használják, ugyanis addig nem tartóztatja fel a többi utasítás lefutását (non-blocking), szemben a szinkron verzióval. A két leggyakrabban használt fájlművelet az írás (write) és olvasás (read). A fájl beolvasásnál opcionálisan beállíthatjuk a karakter kódolást. A magyar ékezetek értelmezéséhez utf8-at állítsunk be. A két fájlművelet használalát bemutatjuk példákon keresztül, mind szinkron, mind aszinkron formájában.

Ezt a szöveget kell beolvasni!
var fs = require('fs');

// fájlból olvasás szinkron megvalósítása

var beolvasott_szoveg = fs.readFileSync('szoveg.txt','utf8');
console.log(beolvasott szoveg);  
//  Ezt a szöveget kell beolvasni.

// fájlba írás szinkron megvalósítása

fs.writeFileSync("masikszoveg.txt", "Ezt a másik szoveget kell másik fájlba kiírni!");

//  fájlból olvasás aszinkron megvalósítás

fs.readFile('szoveg.txt', ,'utf8', (error, data) => {
  if (error){
	console.log(error);
  } else {
	console.log(data);  
	//  Ezt a szöveget kell beolvasni.
  }
});

//  fájlba írás aszinkron megvalósítás

fs.writeFile('masikszoveg.txt', "Ezt a másik szoveget kell másik fájlba kiírni!", 
	(error) => {
		if (err){
			console.log(error);
		} else {
			console.log("A fájlba írás sikeresen megtörtént");
		}
});

Irodalomjegyzék

[1]
Vue.js core team. Vue.js: The Progressive JavaScript Framework. https://vuejs.org, Legutóbb megtekintve: 2019. április 22.
[2]
Vue.js core team. API, Global Config, directive. https://vuex.vuejs.org/vuex.png, Legutóbb megtekintve: 2019. április 22.
[3]
Vue.js core team. API, Global Config, computed. https://vuejs.org/v2/api/#computed, Legutóbb megtekintve: 2019. április 22.
[4]
Vue.js core team. API, Global Config, components. https://vuejs.org/v2/api/#components, Legutóbb megtekintve: 2019. április 22.
[5]
Vue.js core team. Vue-CLI. https://cli.vuejs.org/guide/creating-a-project.html#vue-create, Legutóbb megtekintve: 2019. április 22.
[6]
Vue.js core team. Vue-router. https://router.vuejs.org/guide/#html, Legutóbb megtekintve: 2019. április 22.
[7]
Vue.js core team. Render Functions and JSX. https://vuejs.org/v2/guide/render-function.html, Legutóbb megtekintve: 2019. április 22.
[8]
w3schools core team. JavaScript RegExp Reference. https://www.w3schools.com/jsref/jsref_obj_regexp.asp, Legutóbb megtekintve: 2019. április 22.
[9]
Google Chrome DevTools core team. Chrome DevTools. https://developers.google.com/web/tools/chrome-devtools, Legutóbb megtekintve: 2019. április 22.
[10]
Node.js core team. Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. https://nodejs.org/en/, Legutóbb megtekintve: 2019. április 22.
[11]
NPMJS core team. NPMJS. https://www.npmjs.com, Legutóbb megtekintve: 2019. április 22.
[12]
ExpressJS core team. Express Fast, unopinionated, minimalist web framework for Node.js. https://expressjs.com, Legutóbb megtekintve: 2019. április 22.
[13]
EJS core team. EJS: Embedded JavaScript templating. https://ejs.co, Legutóbb megtekintve: 2019. április 22.
[14]
Olga Filipova. Learning Vue.js 2. Packt Publishing Ltd., Livery Place, 35 Livery Street, Birmingham, B3 2PB, UK, 3, 2016.
[15]
E.F. Codd. A relational Model of Data for Large Shared Data Banks. Communications of the ACM, 13 (6) 1970.
[16]
Papp Edit. Adatbáziskezelés. Booklands 2000 Könyvkiadó Kft., 5600 Békéscsaba, Dr. Becsey Oszkár u. 42., 1, 2004.
[17]
Nemzeti Szakképzési és Felnőttképzési hivatal. Szoftverfejlesztő tanfolyam. https://www.nive.hu, Legutóbb megtekintve: 2019. április 22.
[18]
JavaScript.info core team. JavaScript.info. https://javascript.info/promise-basics, Legutóbb megtekintve: 2019. április 22.
[19]
Craig Buckler. Sitepoint (JavaScript) - Understanding ES6 Modules. https://www.sitepoint.com/understanding-es6-modules/, Legutóbb megtekintve: 2019. április 22.