A modern JavaScript fejlesztésben kulcsszerepet kapnak az eszközök, amelyek segítenek fenntartani a kód minőségét, beleértve a kód formázást, a hibák ellenőrzését és a szabályok betartását. A Prettier és Husky olyan eszközök, amelyek automatikusan segíthetnek a kód tisztaságának és szabványainak megőrzésében, valamint a csapatmunka során a kód konzisztenciáját biztosítják.

A Prettier egy automatikus kódformázó eszköz, amely segít a JavaScript, TypeScript, HTML, CSS, Markdown és JSON fájlok egységes formázásában. Azonban előfordulhat, hogy bizonyos fájlokat, mint például a package-lock.json, nem szükséges formázni, mivel ezek a fájlok eszközök által generáltak, és nem szükségesek a formázás szempontjából. Ekkor célszerű létrehozni egy .prettierignore fájlt, amelyben megadhatjuk a kizárt fájlokat, például:

csharp
# a .prettierignore fájlban
package-lock.json

Ez biztosítja, hogy a Prettier ne alkalmazza a formázást a megadott fájlokra. Miután megismerkedtünk a Prettier alapvető használatával, fontos tisztában lennünk azzal, hogy hogyan biztosítható annak következetes használata a csapatmunka során.

A legjobb módja annak, hogy az ESLint és a Prettier eszközöket folyamatosan alkalmazzuk, az a szerkesztői integráció. A megfelelő bővítmények telepítésével a szerkesztőnkben biztosíthatjuk, hogy az ESLint automatikusan javítja a hibákat, és a Prettier a formázást minden egyes fájl mentésekor alkalmazza. Így nem kell a formázásra gondolnunk, hanem teljes mértékben a kód viselkedésére összpontosíthatunk. Azonban nem feltételezhetjük, hogy minden munkatársunk ugyanígy dolgozik, és itt jön képbe a Husky.

A Husky eszközzel a git pre-commit hook mechanizmusát használhatjuk arra, hogy minden commit előtt automatikusan futtassunk egy szkriptet, például a Prettier-t. Ehhez először telepítenünk kell a Husky-t a projektünk fejlesztői függőségeként:

lua
$ npm install --save-dev husky

Ezután futtathatjuk a Husky init szkriptet:

csharp
$ npx husky init

Ez létrehozza a szükséges fájlokat és beállítja a git hook-okat. Ha a projektünk nem a git tároló gyökerében található, például ha egy almappában van, akkor a prepare szkriptet módosítanunk kell egy külső shell szkriptre, amit prepare.sh-nek nevezhetünk.

A prepare.sh szkript létrehozása után a következő lépés a pre-commit hook konfigurálása, hogy a Prettier automatikusan lefusson minden commit előtt. A pre-commit szkript így nézhet ki:

bash
#!/bin/env bash
cd "$(dirname "$(readlink -f "$0")")/.." prettier . --write git update-index --again

Ez biztosítja, hogy minden commit előtt a módosított fájlokat automatikusan formázza a Prettier, így nem kell külön manuálisan formázni őket. Fontos megjegyezni, hogy bár minden fájl formázása minden commit előtt hasznos lehet, nagyobb projektek esetén nem ideális minden fájl újraformázása minden alkalommal. Erre a problémára a lint-staged eszköz kínál megoldást, amely lehetővé teszi, hogy csak a staged fájlokkal dolgozzunk, így gyorsabbá és hatékonyabbá téve a folyamatot.

A Husky segítségével nemcsak a fájlok formázása végezhető el, hanem statikus elemző eszközök, például az ESLint vagy a TypeScript típusellenőrzés is futtathatóak. Azonban fontos megérteni a teljesítménnyel kapcsolatos kompromisszumokat: minél több műveletet hajtunk végre a pre-commit hook-ban, annál lassabbá válhat a commit folyamat, különösen akkor, ha a TypeScript típusellenőrzést is hozzáadjuk. Emiatt a nagyobb projektek gyakran elkerülik a TypeScript használatát közvetlenül a pre-commit hook-ban, és inkább egy folyamatos integrációs (CI) rendszert használnak, amely a commit után futtatja a típusellenőrzést.

Összegzésül elmondható, hogy a modern JavaScript eszközök, mint a Prettier és a Husky, jelentősen javíthatják a kód minőségét és konzisztenciáját, miközben minimalizálják a manuális formázás és hibajavítás szükségességét. Az automatikus kódformázás és a statikus elemzés eszközei segítenek a fejlesztőknek abban, hogy a lehető legjobb kódot írják, és a csapatok számára fenntartható fejlesztési környezetet biztosítanak.

Hogyan kezeljük a kéréseket és optimalizáljuk a Node.js-t?

A webes alkalmazások teljesítménye kritikus tényezővé vált, különösen a nagy forgalmú rendszerek esetében, ahol minden egyes millisekundum számít. A Node.js egyedülálló megközelítést alkalmaz a webkiszolgálók kezelésében, amely lehetővé teszi a gyorsabb válaszidőt és a jobb erőforrás-kihasználtságot, de ehhez ismerni kell a háttérben zajló folyamatokat.

A hagyományos webkiszolgálók, mint az Apache, több szálat használnak a párhuzamos kérések kezelésére. Ez azonban nem mentes az overhead-től. Míg egy kérés feldolgozása alatt a CPU egy szálon dolgozik, más szálak várakoznak a sorukra. Az Apache ebben az esetben szálakra osztja a munkát, de a szálak létrehozása és fenntartása plusz erőforrásokat igényel, ami a rendszer hatékonyságát csökkentheti. Ezzel szemben a Node.js, amely JavaScript alapú, egyetlen szálon fut, de a nem blokkoló I/O segítségével képes más kérések kezelésére, amíg az aktuális feladat be nem fejeződik.

Vegyük például a következő egyszerű Node.js kódot:

javascript
function indexHandler(req, res) {
fs.readFile("index.html", "utf8", (html) => { res.send(html); }); }

Ez a kód szintén nem blokkolja a szálat. A fs.readFile függvény egy callback-et használ, amely akkor hajtódik végre, amikor a fájl olvasása befejeződött. Így a CPU szabadon végezhet más feladatokat, amíg az I/O művelet tart. Ez a nem blokkoló megközelítés javítja az alkalmazás válaszidejét, és csökkenti a rendszer terhelését.

Fontos megjegyezni, hogy a JavaScript egy szálon futó nyelv, így minden műveletet sorban kell végrehajtani. Ha azonban nem blokkoljuk a szálat, akkor több kérést is kezelhetünk párhuzamosan, anélkül, hogy egy-egy kérés túl sok időt venne el. Ez a koncepció az async/await szintaxis használatával tovább egyszerűsíthető, mint az alábbi példában:

javascript
async function indexHandler(req, res) {
const html = await fsPromises.readFile("index.html", "utf8"); res.send(html); }

Az async/await szintaxis révén nemcsak hogy elkerüljük a callback-ek összetettségét, de a kódunk is könnyebben olvashatóvá válik, miközben megőrzi a nem blokkoló I/O előnyeit.

Ezen kívül, ha hosszabb számításokat vagy I/O műveleteket kell végezni a szálban, akkor azt worker szálak segítségével végezhetjük el, amelyeket az ES2017-es verzió óta támogat a JavaScript. Ezek a worker szálak lehetővé teszik, hogy a hosszú ideig tartó feladatok ne akadályozzák a fő szál végrehajtását.

A Node.js egyedülálló abban is, hogy a globális változókat és API-kat más megközelítéssel biztosítja. A böngészőkkel ellentétben, ahol a globális változók a window objektumon keresztül elérhetők, a Node.js az API-kat modulok