Node.js va Express

Node.js nima?

Shu paytgacha siz JavaScript'ni faqat brauzerda ishlatib keldingiz: sahifadagi tugmalar, formalar, DOM bilan ishlash. Endi esa JavaScript'ni serverda โ€” o'z kompyuteringizda yoki uzoq masofadagi mashinada โ€” ishga tushirasiz. Bunga Node.js imkon beradi. Ushbu darsda Node.js nima ekanligini, u qanday ishlashini va nima uchun mashhurligini chuqur o'rganamiz.

Node.js nima?

Node.js โ€” bu JavaScript kodini brauzerdan tashqarida, ya'ni to'g'ridan-to'g'ri operatsion tizimda ishga tushirishga imkon beradigan ish muhiti (runtime). U 2009-yilda Ryan Dahl tomonidan yaratilgan.

Brauzerda JavaScript sahifa bilan ishlaydi: document, window, alert kabi obyektlarga ega. Node.js'da esa bular yo'q โ€” o'rniga serverga xos imkoniyatlar bor: fayllarni o'qish/yozish, tarmoq so'rovlarini qabul qilish, ma'lumotlar bazasiga ulanish va hokazo.

Muhimi shundaki, til bir xil. Siz bilgan let, funksiyalar, obyektlar, Promise, async/await โ€” barchasi Node.js'da ham xuddi shunday ishlaydi. Faqat atrof-muhit (mavjud obyektlar va modullar) boshqacha.

V8 dvigateli

JavaScript kodi o'zicha ishlamaydi โ€” uni ishga tushiradigan dvigatel (engine) kerak. Google Chrome brauzeri V8 nomli dvigateldan foydalanadi. V8 juda tez: u JavaScript kodini mashina kodiga (protsessor tushunadigan tilga) o'giradi.

Node.js aynan shu V8 dvigatelini oladi va uning atrofiga server imkoniyatlarini qo'shadi. Ya'ni Node.js = V8 + fayl tizimi, tarmoq va boshqa modullar.

Shuning uchun Chrome'da ishlaydigan tezkor zamonaviy JavaScript sintaksisi Node.js'da ham ishlaydi โ€” ikkalasi ham bir xil V8 dvigatelidan foydalanadi.

Bir oqimli va event loop

Node.js'ning eng muhim xususiyatlaridan biri โ€” u bir oqimli (single-threaded). Ya'ni sizning kodingiz asosan bitta oqimda (thread) ketma-ket ishlaydi. Bu g'alati tuyulishi mumkin: bir oqimda qanday qilib minglab foydalanuvchiga xizmat ko'rsatiladi?

Javob โ€” event loop (hodisalar sikli) va bloklamaydigan (non-blocking) I/O. Buni tushunish uchun oshxonadagi bitta ofitsiantni tasavvur qiling.

Ofitsiant bitta (bir oqim). U mijozdan buyurtma oladi va oshpazga uzatadi. Keyin ovqat tayyor bo'lishini kutib turmaydi โ€” darhol boshqa mijozga o'tadi. Ovqat tayyor bo'lganda oshpaz xabar beradi, ofitsiant esa uni olib boradi. Shu tariqa bitta ofitsiant ko'plab mijozga samarali xizmat ko'rsatadi.

Node.js xuddi shunday ishlaydi. Event loop โ€” bu doimo aylanib turuvchi sikl. U bajarilishi kerak bo'lgan vazifalarni navbatga (queue) qo'yadi va birma-bir bajaradi. Uzoq davom etadigan operatsiyalar (fayl o'qish, tarmoq so'rovi) fonda bajariladi, natija tayyor bo'lganda esa callback chaqiriladi.

Bloklamaydigan I/O

I/O (Input/Output) โ€” kirish/chiqish operatsiyalari: fayl o'qish, ma'lumotlar bazasiga so'rov, tarmoq so'rovi. Bular sekin operatsiyalar โ€” protsessor bilan solishtirganda ular abadiyatga cho'ziladi.

Bloklaydigan (blocking) yondashuvda kod fayl o'qib bo'lguncha kutib turadi va boshqa hech nima qilmaydi. Bu vaqtni behuda sarflash.

// Bloklaydigan (sinxron) โ€” kutib turadi:
const data = fs.readFileSync('katta-fayl.txt');
console.log(data); // fayl o'qilguncha bu qator ishga tushmaydi
console.log('Keyingi ish'); // va bu ham kutadi

Bloklamaydigan (non-blocking) yondashuvda esa Node.js fayl o'qishni fonda boshlaydi va darhol keyingi qatorga o'tadi. Fayl tayyor bo'lganda callback chaqiriladi:

// Bloklamaydigan (asinxron) โ€” kutmaydi:
fs.readFile('katta-fayl.txt', (err, data) => {
  console.log(data); // fayl tayyor bo'lganda ishga tushadi
});
console.log('Keyingi ish'); // darhol ishga tushadi, kutmaydi

Aynan shu bloklamaydigan model tufayli Node.js bir oqimda bo'lishiga qaramay ko'plab bir vaqtdagi (concurrent) ulanishlarni samarali boshqaradi. U kutish o'rniga boshqa vazifalarni bajaradi.

Bloklamaydigan I/O va event loop tufayli Node.js ayniqsa ko'p so'rovli, kam hisob-kitobli ilovalar (API serverlari, real-time chatlar, veb-ilovalar) uchun juda mos keladi.

Node.js qachon ishlatiladi?

Node.js universal vosita, lekin ayrim vazifalar uchun ayniqsa yaxshi:

Node.js og'ir hisob-kitob (masalan, murakkab matematik modellashtirish yoki tasvirni qayta ishlash) uchun ideal emas, chunki bir oqim uzoq hisob-kitobda band bo'lib qolsa, event loop bloklanadi. Bunday holatlar uchun boshqa yechimlar (worker threads, alohida servislar) qo'llaniladi.

Node.js'ni o'rnatish

Node.js'ni nodejs.org saytidan yuklab olishingiz mumkin. Ikki versiya taklif etiladi:

Yangi boshlovchilar uchun LTS versiyasi tavsiya etiladi. O'rnatgach, terminalda versiyani tekshiring:

node -v
# v20.11.0

npm -v
# 10.2.4

Agar versiya raqamlari chiqsa โ€” Node.js muvaffaqiyatli o'rnatilgan. node โ€” Node.js'ning o'zi, npm esa u bilan birga keladigan paketlar menejeri (keyingi darsda batafsil).

Bir nechta Node.js versiyalarini boshqarish uchun nvm (Node Version Manager) vositasidan foydalanish qulay. U turli loyihalar uchun turli versiyalarni o'rnatish va almashtirishga imkon beradi.

Birinchi skript

Node.js kodini yozib, ishga tushirib ko'raylik. Bir papkada app.js nomli fayl yarating va quyidagini yozing:

// app.js
console.log('Salom, Node.js!');

const ism = 'Ali';
console.log('Xush kelibsiz, ' + ism);

Endi terminalda shu papkaga o'ting va faylni ishga tushiring:

node app.js

Natija:

Salom, Node.js!
Xush kelibsiz, Ali

Tabriklaymiz โ€” siz brauzersiz, to'g'ridan-to'g'ri operatsion tizimda JavaScript kodini ishga tushirdingiz! Bu yerda console.log natija terminalga chiqadi (brauzerdagidek konsolga emas).

node buyrug'ini argumentsiz ishga tushirsangiz (shunchaki node), REPL (interaktiv rejim) ochiladi. Unda JavaScript ifodalarini birma-bir kiritib, natijani darhol ko'rish mumkin. Chiqish uchun .exit yozing yoki Ctrl+Cni ikki marta bosing.

Xulosa