Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. Runtime: til emas, muhit
- 2.1 Qisqa eslatma
- 2.2 Node qanday paydo bo'ldi
- 3. Node ichida nima bor
- 3.1 Uch qatlam
- 3.2 V8 — oshpaz
- 3.3 libuv — yordamchilar va texnika
- 3.4 C++ bindings — ofitsiant
- 3.5 Bitta chaqiruvning yo'li
- 4. Bitta thread, lekin yolg'iz emas
- 4.1 "Node bir threadli" — qisman to'g'ri
- 4.2 Bu nimani anglatadi
- 5. Node va brauzer: nima umumiy, nima farqli
- 5.1 Umumiy qism
- 5.2 Farqli qism
- 5.3 Node — yagona runtime emas
- 6. Node'ni terminaldan tekshirish
- 6.1 process.versions — ichida nima bor
- 6.2 node -e va node -p — fayl yozmasdan
- 6.3 REPL buyruqlari: .help va .editor
- 7. CLI qadami: valyuta loyihasi va birinchi o'lchov
- 7.1 Bu qismning loyihasi
- 7.2 Birinchi o'lchov: CLI'ning pastki chegarasi
- 8. Ko'p uchraydigan xatolar
- 8.1 Node kodini brauzerda ishga tushirish
- 8.2 "Node bir threadli, demak sekin"
- 8.3 node -e da natijani kutish
- 8.4 .mjs o'rniga .js saqlash
- 9. Mashqlar
- 1-mashq (oson): bo'sh joylarni to'ldiring
- 2-mashq (o'rta): kim bajaradi?
- 3-mashq (qiyin): muhitni aniqlovchi funksiya
- 4-mashq: CLI qadami — muhit hisoboti
- 10. Real ishda
- Xulosa
- Manbalar
Node.js nima: runtime, V8 va libuv
Qisqacha: Node.js — JavaScript'ni brauzerdan tashqarida bajaradigan runtime. Uning ichida uch qatlam bor: V8 JavaScript kodini bajaradi, libuv fayl, tarmoq va taymerlarni kutib turadi (event loop ham shu yerda), C++ bindings esa JavaScript funksiyasini shu ikkisiga ulaydi. Sizning JavaScript kodingiz bitta thread'da ishlaydi, lekin kutish ishini Node operatsion tizim va o'z yordamchi thread'lariga topshiradi.
Bu darsda
- Node.js'ning uch qatlamini (V8, libuv, C++ bindings) o'z so'zingiz bilan tushuntira olasiz.
fs.readFilechaqirilganda chaqiruv qaysi qatlamlardan o'tishini ayta olasiz.- Node va brauzer farqini jadval bilan ko'rsatasiz: nima umumiy, nima faqat bittasida.
process.versions, REPL buyruqlari (.help,.editor),node -evanode -pbilan ishlaysiz.- Bu qismning loyihasi —
valyutaCLI vositasi — nima ekanini va qanday o'lchanishini bilasiz.
Oldin bilishingiz kerak: Node.js nima va uni o'rnatish, Sinxron va asinxron kod, Event loop, JS dvigateli ichida.
1. Nega bu kerak?
Yakuniy Next.js loyiha darsida portfolio v2 ni tugatdingiz. U yerda server kodi ham bor edi: Route Handler, Server Actions, build. Hammasi Node'da ishladi. Lekin Next uni sizdan yashirdi: siz faqat page.tsx yozdingiz, qolganini framework qildi.
Endi parda ochiladi. 24-qismda Node'ning o'zini o'rganamiz: jarayon, fayllar, oqimlar, xatolar, paket nashri. 25-qismdan boshlab esa backend yozasiz — HTTP server, API, ma'lumotlar bazasi. Ularning hammasi shu qismdagi poydevorga tayanadi.
Node bilan oldin ham uchrashgansiz. 03-qismda uni o'rnatdingiz va node fayl.js bilan ishga tushirdingiz. 11-qismda readFileSync va readFile farqini ko'rdingiz. 23-qismda Runtime'lar: Node va Edge darsida "runtime" so'zini eshitdingiz. Bu darsda shu bo'laklar bitta rasmga yig'iladi.
Hayotiy o'xshatish: «Bahor» oshxonasini eslang. Oshpaz — bitta, u buyurtmani o'qib, ovqatni tayyorlaydi. Lekin oshpaz bozorga o'zi bormaydi, qozon qaynashini ham tik turib kutmaydi. Buning uchun yordamchilar va texnika bor. Node'da oshpaz — V8, yordamchilar va texnika — libuv va operatsion tizim. Ularni bog'laydigan ofitsiant — C++ bindings.
Maslahat: Bu qismdagi Node'ga xos kod bloklari ostida «Ishga tushir» tugmasi yo'q. Saytdagi natija oynasi — brauzer, unda
process,fs,Bufferkabi Node imkoniyatlari yo'q. Bunday kodni o'z kompyuteringizda sinang: faylga.mjskengaytmasi bilan saqlang va terminaldanode fayl.mjsdeb yozing. Ostidagi chiqishni biz Node 24.21.0 da ishga tushirib oldik. Toza JavaScript bloklari (Promise, taymer,URL) esa saytda ham ishlaydi.
2. Runtime: til emas, muhit
2.1 Qisqa eslatma
Runtime (bajarish muhiti) — kodni ishga tushiradigan dastur va unga beriladigan imkoniyatlar to'plami. Bu ta'rifni Node.js nima va uni o'rnatish darsida ko'rgan edingiz. JavaScript — til. Brauzer va Node — shu tilni bajaradigan ikki xil runtime.
Sinxron va asinxron kod darsida bu fikrni boshqa so'zlar bilan aytgan edik: dvigatel (engine) kodni bajaradi, host muhit unga tashqi dunyoni — taymer, fayl, tarmoqni — beradi. Node — host muhit. Endi uning ichiga qaraymiz.
2.2 Node qanday paydo bo'ldi
2009-yilgacha JavaScript deyarli faqat brauzerda yashardi. Ryan Dahl ismli dasturchi bir g'oyani sinab ko'rdi. Chrome'ning V8 dvigatelini brauzerdan sug'urib olib, unga fayl va tarmoq bilan ishlash imkonini qo'shdi. Asosiy maqsad — kutish paytida bo'sh turmaydigan server yozish edi. Bu g'oya keyingi darsning mavzusi: Blocking va non-blocking I/O.
Shu ish uchun alohida C kutubxonasi yozildi — libuv. Bugun Node'ni OpenJS Foundation tashkiloti boshqaradi, kodi ochiq. Har yili yangi asosiy versiya chiqadi. Kursda Node 24 ishlatamiz: barcha o'lchovlar Node 24.21.0 da olingan.
Tekshirib ko'ring: Do'stingiz "Node — JavaScript'ning server versiyasi, unda til boshqacha" dedi. Nima deysiz?
Javob
Til bir xil — JavaScript. let, funksiyalar, Promise, klasslar Node'da ham, brauzerda ham bir xil ishlaydi. Farq — tildan tashqaridagi imkoniyatlarda: Node'da document yo'q, lekin fayllar, jarayon va tarmoq bor. Node — runtime, til emas.
3. Node ichida nima bor
3.1 Uch qatlam
Sxemaga yuqoridan pastga qarang. Sizning kodingiz eng tepada, operatsion tizim eng pastda. Har qatlam faqat qo'shnisi bilan gaplashadi.
flowchart TB
K["Sizning kodingiz"] --> L["Node modullari: fs, crypto"]
L --> B["C++ bindings"]
B --> V["V8: JS'ni bajaradi"]
B --> U["libuv: event loop, I/O"]
B --> C["OpenSSL, zlib, SQLite"]
U --> T["Thread pool"]
U --> O["Operatsion tizim"]
T --> OHar qatlam haqida bir gapdan:
| Qatlam | Nima qiladi | Qaysi tilda |
|---|---|---|
| Node modullari | fs, path, crypto kabi tayyor API |
JavaScript |
| C++ bindings | JS chaqiruvini C/C++ funksiyasiga ulaydi | C++ |
| V8 | JS kodini tahlil qiladi va bajaradi | C++ |
| libuv | event loop, fayl, tarmoq, taymer | C |
3.2 V8 — oshpaz
V8 — Google yozgan JavaScript dvigateli. Chrome ham, Node ham aynan shu dvigateldan foydalanadi. U kodni o'qiydi, bytecode'ga aylantiradi va issiq joylarini JIT bilan tezlashtiradi. Bularni JS dvigateli ichida darsida --trace-opt bilan ko'rgan edingiz.
Muhim cheklov: V8 o'zi faylni o'qiy olmaydi, tarmoqqa ham chiqa olmaydi. Uning dunyosi — o'zgaruvchilar, funksiyalar, call stack va xotira (heap). Hatto setTimeout ham V8 ichida yo'q. Uni har bir host o'zi qo'shadi.
3.3 libuv — yordamchilar va texnika
libuv — Node uchun yozilgan C kutubxonasi. Uning ikki asosiy vazifasi bor:
- Event loop — navbatdagi tayyor callback'larni birin-ketin V8 ga beradigan sikl. Brauzerdagi event loop'ni bilasiz. Node'dagisi shu libuv ichida aylanadi va uning fazalari bor — Event loop fazalari chuqur darsida ochamiz.
- Asinxron I/O — I/O (input/output, kiritish-chiqarish) — dasturning tashqi dunyo bilan almashuvi: diskdan o'qish, tarmoqqa yozish, terminaldan klaviatura. libuv bu ishlarni operatsion tizimga topshiradi. Tizim tayyor bo'lganini xabar qilganda, libuv callback'ni navbatga qo'yadi.
Ba'zi ishlarni operatsion tizim "kutib turing, xabar beraman" uslubida qila olmaydi. Masalan, ko'p tizimlarda fayl o'qish shunday. Bunday ishlar uchun libuv'da thread pool (thread'lar havzasi) bor — sukut bo'yicha 4 ta yordamchi thread. Ular og'ir ishni bajarib, natijani event loop'ga qaytaradi. Batafsil — libuv thread pool va OS asinxron I/O darsida.
3.4 C++ bindings — ofitsiant
C++ bindings (bog'lovchilar) — JavaScript funksiyasini C yoki C++ dagi funksiyaga ulaydigan qatlam. Siz readFile(...) deb yozasiz — bu oddiy JavaScript funksiya. Uning ichida bir joyda binding chaqiriladi va ish libuv'ga o'tadi.
Bindings'ni o'zingiz deyarli yozmaysiz. Lekin ular borligini bilish ikki narsani tushuntiradi:
- Nega
fs,crypto,zlibtez ishlaydi — og'ir qismi JavaScript'da emas, C/C++ da. - Nega ba'zi npm paketlari o'rnatishda kompilyatsiya so'raydi — ularda o'z C++ qismi bor (native addon). Bunga paketlar bilan ishlaganda duch kelasiz.
3.5 Bitta chaqiruvning yo'li
Endi hammasini bitta chaqiruvda ko'raylik. «Bahor» menyusini fayldan o'qiymiz:
import { writeFile, readFile } from "node:fs/promises";
await writeFile("menyu.txt", "osh 35000\nmanti 30000");
console.log("1. readFile chaqirildi");
const vada = readFile("menyu.txt", "utf8");
console.log("2. JS davom etyapti, fayl hali o'qilmoqda");
const matn = await vada;
console.log("3. Fayl keldi:", matn.split("\n").length, "qator");Konsolda:
1. readFile chaqirildi
2. JS davom etyapti, fayl hali o'qilmoqda
3. Fayl keldi: 2 qatorQatlamlar bo'yicha nima bo'ldi:
- V8
readFile(...)ni bajardi. Bunode:fs/promisesmodulidagi JavaScript funksiya. - Funksiya binding orqali libuv'ga "shu faylni o'qi" deb topshirdi va darhol Promise qaytardi.
- V8 keyingi qatorga o'tdi — "2." chiqdi. Shu paytda thread pool'dagi bitta thread diskdan o'qiyapti.
- O'qish tugadi. libuv buni event loop'da sezdi va natijani qaytardi. Promise bajarildi.
awaitdan keyingi kod ishladi — "3." chiqdi.
Kodning o'zi sizga async/await darsidan tanish. Yangi narsa — uning ostidagi yo'l.
Tekshirib ko'ring: Yuqoridagi misolda faylni aynan kim o'qidi: V8mi, libuv'mi yoki operatsion tizimmi?
Javob
Diskdan o'qishni operatsion tizim bajaradi — faqat u diskka kira oladi. libuv bu so'rovni thread pool'dagi yordamchi thread orqali tizimga beradi va javobni kutadi. V8 esa umuman o'qimaydi: u faqat JavaScript'ni bajaradi va shu orada bo'sh emas — keyingi qatorga o'tadi.
4. Bitta thread, lekin yolg'iz emas
4.1 "Node bir threadli" — qisman to'g'ri
Intervyuda ko'p so'raladigan gap: "Node.js single-threaded". Bu sizning JavaScript kodingiz uchun to'g'ri. Call stack bitta, bir paytda bitta funksiya bajariladi. Bu fikrni Sinxron va asinxron kod darsida brauzer uchun ko'rgan edingiz.
Lekin Node jarayonining o'zida bir nechta thread bor: libuv thread pool, V8'ning xotirani tozalovchi (garbage collector) yordamchilari va boshqalar. Ular JavaScript bajarmaydi, sizning kodingizga xizmat qiladi.
Shuning uchun aniq javob shunday: "JavaScript bitta thread'da bajariladi, I/O esa fonda — operatsion tizim va libuv thread'larida".
4.2 Bu nimani anglatadi
Ikkita amaliy xulosa bor:
- Kutish arzon. Fayl, tarmoq yoki taymerni kutayotganda JS thread bo'sh — boshqa ishni qila oladi.
- Hisoblash qimmat. Katta siklda yoki og'ir hisobda JS thread band bo'ladi. Bu paytda boshqa hech bir callback ishlamaydi.
Ikkinchi xulosani Event loop'ni bloklash darsida o'lchab ko'ramiz. Og'ir hisobni boshqa thread'ga chiqarish usuli ham bor — worker'lar, ularni ham shu qismda o'rganasiz.
Diqqat: "Node bir threadli, shuning uchun bitta yadrodan ortiq ishlata olmaydi" — noto'g'ri xulosa. Thread pool va worker'lar boshqa yadrolarda ishlaydi. To'g'risi: sizning oddiy JS kodingiz bitta yadroda ketma-ket bajariladi.
5. Node va brauzer: nima umumiy, nima farqli
5.1 Umumiy qism
Ikkala runtime'da ham bir xil V8 tili va ko'plab bir xil Web API'lar bor. Bu blok saytda ham, Node'da ham bir xil natija beradi — sinab ko'ring:
console.log(typeof globalThis);
console.log(typeof setTimeout);
console.log(typeof fetch);
console.log(typeof URL);
console.log(typeof structuredClone);Konsolda:
object
function
function
function
functionfetch, URL, AbortController, TextEncoder, crypto.randomUUID — bularning hammasi Node'da ham bor va brauzerdagidek ishlaydi. Node so'nggi yillarda ataylab Web standartlariga yaqinlashdi: bitta kod ikki joyda ishlashi qulay. Batafsil ro'yxat — Global obyektlar: Node va brauzer farqi darsida.
5.2 Farqli qism
Endi faqat Node'da ishlaydigan blok. Uni kompyuteringizda .mjs faylga saqlab ishga tushiring:
console.log(typeof window);
console.log(typeof document);
console.log(typeof process);
console.log(typeof Buffer);
console.log(process.release.name);Konsolda:
undefined
undefined
object
function
nodeBrauzer konsolida xuddi shu kod boshqacha natija beradi: window va document — object, process va Buffer esa undefined. Jadval bilan:
| Imkoniyat | Brauzer | Node |
|---|---|---|
document, DOM |
bor | yo'q |
localStorage |
bor | yo'q (fayl bor) |
process, Buffer |
yo'q | bor |
| Fayl, jarayon, terminal | yo'q | bor (fs, child_process) |
| Xavfsizlik | sandbox, sayt cheklovlari | foydalanuvchi huquqlari bilan |
| Kim ishga tushiradi | sahifani ochgan odam | siz yoki server |
Oxirgi ikki qatorga e'tibor bering. Brauzer begona sayt kodini ishga tushiradi, shuning uchun uni sandbox'da qamaydi. Node esa sizning kodingizni sizning huquqlaringiz bilan bajaradi: u har qanday faylni o'chira oladi. npm paketini o'rnatish — o'sha paket kodiga shu huquqni berish demak. Bu mavzuga Permission model darsida qaytamiz.
5.3 Node — yagona runtime emas
JavaScript uchun boshqa server runtime'lari ham bor. Deno va Bun — ikkalasi ham Node'ga o'xshash ishlarni qiladi va Node API'larining katta qismini qo'llab-quvvatlaydi. Runtime'lar: Node va Edge darsida Edge runtime'ni ham ko'rdingiz. Kursda Node'ni o'rganamiz: backend ishlarida u eng keng tarqalgan va qolganlari uning API'siga moslashadi. Node'ni bilsangiz, boshqasiga o'tish oson kechadi.
Tekshirib ko'ring: Quyidagilardan qaysi biri saytdagi «Ishga tushir» oynasida ishlaydi:
new URL("https://example.com/menyu").pathnameyokiprocess.argv? Nega?
Javob
new URL(...) ishlaydi — URL Web API, u brauzerda ham, Node'da ham bor (natija /menyu). process.argv ishlamaydi: process faqat Node'da bor, natija oynasi esa brauzer. Brauzerda process is not defined xatosi chiqadi.
6. Node'ni terminaldan tekshirish
6.1 process.versions — ichida nima bor
Node o'z qatlamlarining versiyalarini process.versions obyektida saqlaydi. Uni chiqaramiz:
const { node, v8, uv, undici, openssl, sqlite } = process.versions;
console.log({ node, v8, uv, undici, openssl, sqlite });Biz Node 24.21.0 da ishga tushirdik (Windows 11, i5-12500H):
{
node: '24.21.0',
v8: '13.6.233.17-node.53',
uv: '1.52.1',
undici: '7.29.1',
openssl: '3.5.8',
sqlite: '3.53.4'
}Har qatorni sxemadagi qatlam bilan solishtiring:
v8— dvigatel. Oxiridagi-node.53— Node jamoasi V8'ga kiritgan o'zgarishlar raqami.uv— libuv.undici—fetchni amalga oshiradigan kutubxona (JavaScript'da yozilgan).openssl— shifrlash va HTTPS uchun,cryptomoduli shunga tayanadi.sqlite— Node 24 ichiga o'rnatilgan kichik ma'lumotlar bazasi.
Bu blokni nocheck qildik: versiyalar sizning Node'ingizda boshqacha bo'lishi mumkin. Shuning uchun sizdagi chiqish raqamlari bilan farq qilsa — xavotir olmang.
Node ichida nechta tayyor modul borligini ham sanash mumkin: node:module dagi builtinModules ro'yxati Node 24.21.0 da 72 ta nom qaytaradi. Ulardan 14 tasi _ bilan boshlanadi — ichki, eskirgan nomlar. To'rttasi esa faqat node: prefiksi bilan chaqiriladi: node:test, node:sqlite, node:sea va node:test/reporters.
6.2 node -e va node -p — fayl yozmasdan
Bitta qatorlik kodni sinash uchun fayl yaratish shart emas. Ikkita bayroq bor:
node -e "kod"— eval: kodni bajaradi. Natijani ko'rish uchunconsole.logkerak.node -p "kod"— print: kodni bajaradi va oxirgi ifoda qiymatini o'zi chiqaradi.
node -e "console.log(35000 * 3)"
node -p "35000 * 3"
node -p "process.versions.v8"
node -p "[process.platform, process.arch]"Biz ishga tushirgan chiqish (Windows 11):
105000
105000
13.6.233.17-node.53
[ 'win32', 'x64' ]Linux'da oxirgi qator [ 'linux', 'x64' ] bo'ladi — buni Node hujjati aytadi, biz Linux'da sinamadik. -p CLI'ni tez tekshirish va shell skriptlar uchun qulay. Masalan, loyihadagi package.json versiyasini olish: node -p "require('./package.json').version".
Diqqat: PowerShell va Git Bash'da qo'shtirnoqlar har xil ishlaydi. Kod ichida matn kerak bo'lsa, tashqarida
"…", ichkarida'…'ishlating — yuqoridagi misollar ikkalasida ham ishlaydi.
6.3 REPL buyruqlari: .help va .editor
REPL'ni Node.js nima va uni o'rnatish darsida kalkulyator sifatida ishlatgan edingiz. Uning nuqta bilan boshlanadigan maxsus buyruqlari bor. .help ularni ko'rsatadi. Biz kirishni fayldan uzatib ishga tushirdik:
$ node
Welcome to Node.js v24.21.0.
Type ".help" for more information.
> .help
.break Sometimes you get stuck, this gets you out
.clear Alias for .break
.exit Exit the REPL
.help Print this help message
.load Load JS from a file into the REPL session
.save Save all evaluated commands in this REPL session to a file
Press Ctrl+C to abort current expression, Ctrl+D to exit the REPLTarjimasi:
.break— ko'p qatorli kiritishda "tiqilib qolsangiz", undan chiqaradi;.clear— xuddi shu..exit— REPL'dan chiqish..load fayl.js— faylni REPL'ga yuklab bajaradi;.save fayl.js— shu sessiyada yozganlaringizni faylga saqlaydi.
Haqiqiy terminalda ro'yxatda yana bitta buyruq ko'rinadi — .editor. U REPL'ni muharrir rejimiga o'tkazadi: bir nechta qator yozasiz, Enter darhol bajarmaydi. Tugatgach Ctrl+D bosasiz — butun bo'lak birga bajariladi, Ctrl+C esa bekor qiladi. Bizning ishga tushirishda kirish terminal emas, fayl edi — shuning uchun Node .editor ni ro'yxatga qo'shmadi. Buni tekshirdik: REPL terminal: true bilan ochilsa, buyruqlar ro'yxatida editor bor, terminal: false bilan — yo'q. Funksiyani bir necha qatorda yozib sinash uchun .editor qulay.
REPL'da yana ikkita foydali narsa: _ (pastki chiziq) — oxirgi natija, Tab — avtomatik to'ldirish. Masalan, process. yozib Tab ni ikki marta bossangiz, process ning barcha xususiyatlari chiqadi.
Endi o'zingiz: REPL'da 35000 * 2 dan keyin _ + 5000 yozsangiz, natija bo'ladi.
7. CLI qadami: valyuta loyihasi va birinchi o'lchov
7.1 Bu qismning loyihasi
Bu qism davomida siz valyuta ni qurasiz — O'zbekiston Markaziy bankining valyuta kurslarini terminalda ko'rsatadigan CLI (command-line interface, buyruq qatori interfeysi) vositasi. CLI — terminalda buyruq yozib ishlatiladigan dastur; node, npm, git — hammasi CLI.
Qism oxirida u npm paketi bo'ladi va shunday ishlaydi (kanonning haqiqiy chiqishi, oflayn rejimda):
$ valyuta kurs USD EUR RUB
Ogohlantirish: offline rejim — saqlangan namuna kurslar (fixtures/) ishlatildi
2026-10-23 holatiga (fixture)
USD 1 11 903.15 -62.36 AQSH dollari
EUR 1 13 329.15 -108.12 EVRO
RUB 1 146.75 0.79 Rossiya rubli
$ valyuta 100 USD
Ogohlantirish: offline rejim — saqlangan namuna kurslar (fixtures/) ishlatildi
100.00 USD = 1 190 315.00 UZSUnga qadamma-qadam qo'shiladi: buyruq argumentlari va chiqish kodlari, fayl kesh, xavfsiz yozish, oqimlar bilan katta CSV, qayta urinish va bekor qilish, testlar, interaktiv rejim, npm'ga tayyor paket. Loyiha oddiy valyuta nomi bilan boshlanadi. npm'ga chiqarishga tayyorlaganda (O'z npm paketingizni nashr qilish darsida) package.json dagi name ni @login/valyuta ga o'zgartirasiz va buni keyingi commit bilan saqlaysiz. Bu yerda login o'rniga npm'dagi foydalanuvchi nomingizni qo'yasiz — oddiy valyuta nomini hamma o'quvchi bir vaqtda ololmaydi. Terminaldagi buyruq nomi esa ikkala holatda ham valyuta bo'lib qoladi.
Loyiha Node process obyekti darsida boshlanadi. Undan oldingi darslarda (#01–#07) kod yozilmaydi — Node ichini o'rganamiz va o'lchaymiz.
7.2 Birinchi o'lchov: CLI'ning pastki chegarasi
CLI'ning muhim xususiyati — sovuq start (cold start): buyruq yozilgandan javob chiqquncha o'tgan vaqt. Har safar yangi Node jarayoni ishga tushadi. Bo'sh jarayonning o'zi qancha turadi?
Kanonda node -e 0 (hech narsa qilmaydigan dastur) 11 marta ishga tushirildi. Mediana — 73.3 ms (eng tezi 63.4, eng sekini 97.8 ms). Bu — har qanday Node CLI'ning pastki chegarasi: V8 ni ishga tushirish, ichki modullarni yuklash, libuv'ni tayyorlash. Undan tezroq Node CLI bo'lmaydi.
Grafikda yakuniy valyuta bilan solishtiring:
- node -e 0bo'sh jarayon73,3 ms
- node dist/bin.jstayyor valyuta103,5 ms
- npm run startnpm orqali458,6 ms
Manba: IlmHamroh kanon o'lchovi, 2026-10-23: Node 24.21.0, Windows 11, i5-12500H; mediana, n=11 va n=15
Nimaga qarang: valyuta ning o'zi bo'sh Node'dan atigi ~30 ms ko'p. Lekin uni npm run orqali chaqirsangiz, vaqt 4 baravar oshadi — npm'ning o'zi ham Node dasturi va u ham ishga tushishi kerak. Bu farqni TypeScript'ni to'g'ridan ishga tushirish darsida tahlil qilamiz.
Bu darsda valyuta ga hech narsa qo'shilmaydi va commit yo'q: CLI uchun hali yozadigan kod yo'q, faqat o'lchov.
8. Ko'p uchraydigan xatolar
8.1 Node kodini brauzerda ishga tushirish
Saytdagi natija oynasiga yoki Chrome konsoliga Node kodini qo'ysangiz:
Uncaught ReferenceError: process is not definedTarjimasi: "ushlanmagan xato: process aniqlanmagan". Brauzerda process yo'q. Yechim: Node kodini terminalda node fayl.mjs bilan ishga tushiring. Teskarisi ham bor: Node'da document.querySelector yozsangiz — ReferenceError: document is not defined.
8.2 "Node bir threadli, demak sekin"
Kutish (fayl, tarmoq) Node'da arzon — JS thread shu orada bo'sh. Sekinlik faqat JS thread'ni band qiladigan og'ir hisobda paydo bo'ladi. Buni "Node yomon" deb emas, "og'ir hisobni to'g'ri joyga chiqarish kerak" deb tushuning.
8.3 node -e da natijani kutish
node -e "35000 * 3"Terminalda hech narsa chiqmaydi — bu xato emas. -e faqat bajaradi, chiqarmaydi. Natija kerak bo'lsa — node -p yoki console.log.
8.4 .mjs o'rniga .js saqlash
Bu qismdagi bloklarda import va top-level await bor. Faylni .js deb saqlasangiz, Node 24 import ni ko'rib, uni baribir modul sifatida bajaradi. Lekin papkada "type" maydonisiz package.json bo'lsa, avval ogohlantirish chiqadi (biz ishga tushirdik):
Warning: Module type of file:///…/a.js is not specified and it doesn't parse as CommonJS.Tarjimasi: "faylning modul turi ko'rsatilmagan va u CommonJS sifatida o'qilmadi". Node faylni ikki marta tahlil qiladi — bu sekinroq. Aniq bo'lishi uchun .mjs ishlating. CommonJS nima ekanini va farqini ES Modules Node'da darsida ko'ramiz.
9. Mashqlar
Mashqlar kurs/mashqlar/24/01-nodejs-nima/ da.
1-mashq (oson): bo'sh joylarni to'ldiring
- JavaScript kodini bajaradigan dvigatel — .
- Event loop va asinxron I/O'ni boshqaradigan C kutubxonasi — .
- JS funksiyasini C/C++ funksiyasiga ulaydigan qatlam — C++ .
- Kodni bajarib, oxirgi qiymatni o'zi chiqaradigan bayroq —
node. - libuv thread pool'idagi thread'lar soni (sukut bo'yicha) — .
Yechim
V8 — dvigatel, u faqat JavaScript'ni bajaradi. libuv — event loop va I/O. Bindings — ofitsiant, JS chaqiruvini C/C++ ga yetkazadi. -p — print; -e esa faqat bajaradi. Thread pool sukut bo'yicha 4 ta thread — buni libuv thread pool va OS asinxron I/O darsida o'zgartirib ko'ramiz.
2-mashq (o'rta): kim bajaradi?
Har ish uchun javob bering: V8, libuv yoki operatsion tizim?
const narx = 35000 * 3;ni hisoblash.- 2 soniyalik taymer vaqti kelganini kuzatish.
- Diskdagi
menyu.txtdan baytlarni o'qish. awaitdan keyingi kodni bajarish.- Tayyor bo'lgan callback'ni navbatdan olib JS'ga berish.
Yechim
- V8 — oddiy JavaScript hisobi.
- libuv — taymerlarni event loop kuzatadi.
- Operatsion tizim — diskka faqat u kiradi (libuv so'rovni yetkazadi).
- V8 —
awaitdan keyingi qism ham JavaScript. - libuv — event loop'ning ishi.
Qoidani eslang: JavaScript qatorini doim V8 bajaradi. Kutish va "tayyor bo'ldi" xabarini libuv kuzatadi. Haqiqiy kiritish-chiqarishni operatsion tizim qiladi.
3-mashq (qiyin): muhitni aniqlovchi funksiya
Ba'zi kutubxonalar bitta kodni brauzerda ham, Node'da ham ishlatadi va qaysi muhitda turganini tekshiradi. muhitniAniqla(g) funksiyasini yozing. U global obyektga o'xshash g ni oladi va qaytaradi:
"node"—g.processbor vag.process.versionsdanodexususiyati bor;"brauzer"—g.windowvag.documentikkalasi ham bor;"noma'lum"— boshqa hollarda.
Ishora: xususiyat bor-yo'qligini ?. bilan tekshiring (Optional chaining). Funksiyani to'rtta soxta obyekt bilan sinang va har birini nom: natija ko'rinishida chiqaring.
Yechim
function muhitniAniqla(g) {
if (g.process?.versions?.node) return "node";
if (g.window && g.document) return "brauzer";
return "noma'lum";
}
const sinovlar = {
node: { process: { versions: { node: "24.21.0" } } },
chrome: { window: {}, document: {} },
yarim: { window: {} },
bosh: {},
};
for (const [nom, g] of Object.entries(sinovlar)) {
console.log(`${nom}: ${muhitniAniqla(g)}`);
}Konsolda:
node: node
chrome: brauzer
yarim: noma'lum
bosh: noma'lumFunksiya haqiqiy globalThis ni emas, parametrni tekshiradi — shuning uchun uni ikkala muhitda bir xil sinash mumkin. O'z kompyuteringizda muhitniAniqla(globalThis) deb chaqirsangiz, Node'da "node" qaytadi. Brauzerda "brauzer". yarim holati muhim: faqat window ga ishonish xavfli — ba'zi test muhitlari uni soxta qilib qo'yadi. Real kutubxonalar ham bir nechta belgini birga tekshiradi.
4-mashq: CLI qadami — muhit hisoboti
valyuta ning bu bosqichida kod yo'q. Kompyuteringizdagi Node'ni o'rganing:
node -p "process.versions"ni ishga tushiring.node,v8,uvversiyalarini yozib oling.- Shu uchta qiymatni bitta qatorda chiqaradigan
node -pbuyrug'ini o'zingiz yozing. - Bo'sh Node necha millisekundda ishga tushishini taxminan o'lchang. PowerShell'da:
Measure-Command { node -e 0 }, Git Bash'da:time node -e 0. 5 marta takrorlang va o'rtasini oling.
Yechim
- Node 24.21.0 da:
node24.21.0,v813.6.233.17-node.53,uv1.52.1. Sizdagi versiya boshqa bo'lsa — kursdagi o'lchovlar bilan raqamlar biroz farq qilishi mumkin. - Masalan:
node -p "[process.versions.node, process.versions.v8, process.versions.uv].join(' | ')". Biz ishga tushirdik:24.21.0 | 13.6.233.17-node.53 | 1.52.1. - Kanon mashinasida mediana 73 ms (63–98). Sizda 50–200 ms oralig'i odatiy: kompyuter tezligi, antivirus va disk ta'sir qiladi. Birinchi ishga tushirish odatda eng sekin — tizim fayllarni hali keshlamagan. Shuning uchun kanon o'lchovida avval bitta "isitish" ishga tushirilib, keyin mediana olinadi.
10. Real ishda
- Backend: Express, NestJS, Fastify, Next.js serveri — hammasi Node ustida. IlmHamroh'ning o'z API'si ham NestJS'da, Node'da ishlaydi.
- Asboblar: npm, Vite, ESLint, TypeScript kompilyatori, Prettier — barchasi Node'da yozilgan CLI'lar. Ular nega ba'zan sekin ishga tushishini endi tushunasiz: har biri yangi Node jarayoni.
- Intervyu savollari: "Node.js nima, til yoki framework?", "Node bir threadlimi?", "libuv nima qiladi?", "Node va brauzerdagi JavaScript farqi?", "V8 nima?". Yaxshi javob qatlamlarni nomlaydi va "JS bitta thread'da, I/O fonda" degan aniq fikrni beradi.
- Muammo tahlili: "Server sekin" degan shikoyatda birinchi savol — JS thread band (og'ir hisob) yoki tashqi narsa sekin (baza, tarmoq)? Bu qatlamlarni bilish to'g'ri savol berishga yordam beradi.
Xulosa
- Node.js — JavaScript runtime: til brauzerdagidek, imkoniyatlar boshqa (fayl, jarayon, tarmoq).
- Uch qatlam: V8 — JS'ni bajaradi; libuv — event loop va asinxron I/O; C++ bindings — ularni bog'laydi.
- JavaScript bitta thread'da bajariladi; kutish operatsion tizim va libuv thread pool'iga topshiriladi.
- Node va brauzerda umumiy Web API'lar ko'p (
fetch,URL, taymerlar);process,Buffer,fs— faqat Node'da,document— faqat brauzerda. process.versions,node -e,node -p, REPL'ning.help,.editor,.load,.save— Node'ni tez tekshirish vositalari.- Bo'sh Node jarayoni ~73 ms — har qanday Node CLI'ning pastki chegarasi.
Keyingi dars: Blocking va non-blocking I/O — nega bitta thread minglab ulanishga xizmat qila oladi va qachon readFileSync xavfli.
Manbalar
- Node.js hujjati — About Node.js: https://nodejs.org/en/about
- Node.js hujjati — REPL (
.editorva boshqa buyruqlar): https://nodejs.org/api/repl.html - Node.js hujjati — Command-line options (
-e,-p): https://nodejs.org/api/cli.html - libuv hujjati — Design overview: https://docs.libuv.org/en/v1.x/design.html
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!