Mundarija (42)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Core modul nima va qanday ulanadi
- 2.2. fs — fayl tizimi (uch shakl — 5.1)
- 2.3. fs — asosiy amallar (CRUD — 0.2)
- 2.4. fs — mavjudlikni tekshirish (to'g'ri usul)
- 2.5. path — yo'l bilan ishlash (0.2 amaliyoti)
- 2.6. os — operatsion tizim ma'lumoti (0.2)
- 2.7. util — yordamchi vositalar
- 2.8. crypto — kriptografiya (xavfsizlik yuragi)
- 2.9. crypto — tasodifiy ma'lumot (token, ID)
- 2.10. crypto — hash (bir tomonlama)
- 2.11. crypto — parol xeshlash (scrypt — 5.15 kirishi)
- 2.12. crypto — HMAC (imzo)
- 2.13. crypto — shifrlash (cipher, ikki tomonlama)
- 2.14. Boshqa foydali core modullar (qisqacha)
- 2.15. Atomic File Writes va Crash-Safety (Halokatga chidamli yozish)
- 2.16. File Descriptor Leaks va EMFILE: too many open files
- 2.17. Path Traversal (Directory Traversal / Zip Slip) xavfsizlik himoyasi
- 2.18. Fayllarni kuzatish: fs.watch vs fs.watchFile va nega chokidar
- 2.19. Universal Web Crypto API (globalThis.crypto)
- 3. Sintaksis — tez ma'lumotnoma
- 4. Batafsil kod namunalari
- Misol 1 — fs/promises bilan to'liq CRUD (2.2, 2.3)
- Misol 2 — JSON "ma'lumotlar bazasi" (mini, fs ustida)
- Misol 3 — path bilan rekursiv papka skaneri (0.2 loyihasi qayta)
- Misol 4 — crypto: token va UUID (2.9)
- Misol 5 — crypto: parol xeshlash (to'liq — 2.11, 5.15)
- Misol 6 — crypto: fayl yaxlitligi (hash — 2.10)
- Misol 7 — os: tizim monitoringi (2.6)
- Misol 8 — util.promisify (eski API → async/await — 2.7)
- 5. To'g'ri va noto'g'ri holatlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- 8. Eng yaxshi amaliyotlar (best practices)
- 9. Amaliy loyiha: "Fayl-Asoslangan Mini Backend Vositalari"
- Maqsad
- Talablar (requirements)
- Maslahatlar (hint)
- "Tayyor" mezonlari (acceptance criteria)
- 10. Xulosa va keyingi bobga ko'prik
- Foydalanilgan rasmiy/ishonchli manbalar
5.3-bob: Core modullar — fs, path, os, util, crypto
5-QISM — Node.js Backend · 3-mavzu
1. Kirish va motivatsiya
5.1-bobda Node arxitekturasini (V8 + libuv), 5.2-bobda npm ekotizimini o'rgandik. Endi Node'ning o'rnatilgan (built-in / core) modullarini — npm'siz, npm installsiz, darrov mavjud kuchli vositalarini — chuqur o'rganamiz. Bular — har bir backend'ning kunlik quroli.
Brauzerdagi JavaScript fayl o'qiy olmasdi, tasodifiy kalit yarata olmasdi, tizim haqida bilmasdi (0.5, 2.14). Node esa core modullar orqali bularning hammasini beradi: fs (fayl tizimi — 0.2), path (yo'l — 0.2), os (operatsion tizim — 0.2), crypto (xavfsizlik, hash, tasodif — 3.5, 5.15), util (yordamchilar). Bular libuv 5.1-bob ustiga qurilgan va asinxron ishlaydi.
Bu modullarni yaxshi bilish — sizni kutubxonaga kamroq bog'liq, kuchliroq dasturchi qiladi. Ko'p paket aslida shu core modullarning "o'ramidir" (masalan bcrypt — crypto ustida; fayl kutubxonalari — fs ustida). Ularni bilsangiz, "pardaning ortida" nima borligini tushunasiz.
O'xshatish: core modullar — uy quruvchining standart asboblar to'plami (bolg'a, arra, o'lchagich) — ular doim qutida, sotib olish shart emas. npm paketlari — maxsus, qo'shimcha asboblar. Yaxshi usta avval standart asboblarni mukammal biladi.
Nega muhim?
- Har backend — fayl (
fs), yo'l (path), xavfsizlik (crypto) ishlatadi. - Parol xeshlash (5.15, 14), token/ID yaratish —
cryptoustida. - Kutubxona ichini tushunish — ko'p paket core modullarning o'rami.
- Streams 5.4-bob, HTTP 5.5-bob — core modullar ustiga quriladi.
2. Nazariya — chuqur tushuntirish
2.1. Core modul nima va qanday ulanadi
Core (built-in) modul — Node bilan birga keladigan, npm install talab qilmaydigan modul. Ulanishi (2.14: modullar):
// CommonJS (an'anaviy Node)
const fs = require("fs");
const fs = require("node:fs"); // "node:" prefiks — aniq core ekanini bildiradi (tavsiya)
// ESM (zamonaviy — package.json'da type: module — 5.2)
import fs from "node:fs";
import { readFile } from "node:fs/promises"; // promise versiyasi (2.3)
node:prefiks (tavsiya):require("node:fs")— bu aniq core modul (npm'dan emas) ekanini bildiradi; chalkashlik va xavfsizlik (typosquatting — 5.2) ni oldini oladi. Zamonaviy kodda ishlatiladi.
2.2. fs — fayl tizimi (uch shakl — 5.1)
fs (file system — 0.2) modulining har metodi uch shaklda (nodejs.org):
1. SYNC (blocking): fs.readFileSync() → server'da ISHLATMANG 5.1-bob
2. CALLBACK (async): fs.readFile(..., cb) → eski async usul
3. PROMISE (async): fs.promises.readFile() → zamonaviy, eng yaxshi (2.11)// 1. Sync (blocking — faqat skript/start vaqti, server'da emas — 5.1)
const data = fs.readFileSync("fayl.txt", "utf8");
// 2. Callback (error-first — 5.1)
fs.readFile("fayl.txt", "utf8", (err, data) => {
if (err) return console.error(err);
console.log(data);
});
// 3. Promise (zamonaviy — async/await bilan — 2.11)
import { readFile } from "node:fs/promises";
const data = await readFile("fayl.txt", "utf8");Tavsiya: server kodida
fs/promises(async/await — 2.11) ishlating. Sync — faqat dastur boshlanishida (config o'qish) yoki bir martalik skript. Callback — eski kod.
2.3. fs — asosiy amallar (CRUD — 0.2)
import { readFile, writeFile, appendFile, unlink, mkdir, readdir, stat, rm } from "node:fs/promises";
// O'qish
const data = await readFile("a.txt", "utf8"); // matn (utf8 — 0.1)
const buf = await readFile("rasm.png"); // Buffer (binary — 0.1, 2.7)
// Yozish (yangidan — eski o'chadi)
await writeFile("a.txt", "Salom dunyo", "utf8");
// Qo'shish (oxiriga)
await appendFile("log.txt", "yangi qator\n");
// O'chirish
await unlink("a.txt"); // fayl
await rm("papka", { recursive: true }); // papka (ichi bilan — 0.3: rm -r)
// Papka
await mkdir("yangi-papka", { recursive: true }); // -p kabi (0.3)
const fayllar = await readdir("papka"); // ro'yxat (0.3: ls)
// Metadata (0.2)
const info = await stat("a.txt");
info.size; // bayt (0.1)
info.isDirectory(); // papkami?
info.birthtime; // yaratilgan sana (2.9)2.4. fs — mavjudlikni tekshirish (to'g'ri usul)
import { access, constants } from "node:fs/promises";
// ✅ To'g'ri — access bilan (try/catch — 2.12)
try {
await access("fayl.txt", constants.F_OK);
console.log("Fayl bor");
} catch {
console.log("Fayl yo'q");
}
// ❌ Eski existsSync — race condition xavfi (tekshirish va ishlatish orasida o'zgarishi mumkin)
// Ko'pincha: tekshirmasdan ishlatib, xatoni ushlash afzal (2.12)
try {
const data = await readFile("fayl.txt", "utf8");
} catch (err) {
if (err.code === "ENOENT") console.log("Fayl yo'q"); // 0.2: ENOENT
}2.5. path — yo'l bilan ishlash (0.2 amaliyoti)
path — fayl yo'llarini platformaga mos (Windows \ vs Unix / — 0.2) boshqaradi:
import path from "node:path";
path.join("src", "utils", "a.js"); // "src/utils/a.js" (OS mos — 0.2)
path.resolve("a.js"); // absolute yo'l (0.2)
path.basename("/home/ali/a.js"); // "a.js"
path.dirname("/home/ali/a.js"); // "/home/ali"
path.extname("a.js"); // ".js"
path.parse("/home/ali/a.js"); // {root, dir, base, name, ext}
path.sep; // "/" yoki "\" (OS)
// __dirname bilan (eng muhim — 0.2, 5.1)
const faylYol = path.join(import.meta.dirname, "data.json"); // ESM'da
// CommonJS'da: path.join(__dirname, "data.json")Yo'lni qo'lda yopishtirmang (
"src" + "/" + "a.js") — Windows'da buziladi 0.2-bob. Doimpath.join.__dirname/import.meta.dirnamebilan — fayl joyiga nisbatan ishonchli yo'l.
2.6. os — operatsion tizim ma'lumoti (0.2)
import os from "node:os";
os.platform(); // "linux" / "win32" / "darwin" (0.2)
os.arch(); // "x64" / "arm64" (0.1)
os.cpus(); // CPU yadrolari massivi 0.1-bob — .length = yadrolar soni
os.totalmem(); // jami RAM, bayt (0.1)
os.freemem(); // bo'sh RAM
os.homedir(); // foydalanuvchi home papkasi (0.2)
os.tmpdir(); // vaqtinchalik papka (0.2)
os.hostname(); // kompyuter nomi
os.uptime(); // tizim ishlash vaqti (sekund)Amaliy:
os.cpus().length— cluster (5.1: ko'p process) yoki worker thread sonini aniqlashda;os.tmpdir()— vaqtinchalik fayl uchun;os.freemem()— monitoring 10.9-bob.
2.7. util — yordamchi vositalar
util — turli foydali yordamchilar (nodejs.org):
import util from "node:util";
// promisify — callback funksiyani Promise'ga aylantiradi 2.11-bob — eng muhim
const readFilePromise = util.promisify(fs.readFile);
const data = await readFilePromise("a.txt", "utf8");
// inspect — obyektni chuqur, chiroyli ko'rsatish (debug — 15.5)
console.log(util.inspect(murakkabObyekt, { depth: null, colors: true }));
// types — tur tekshirish
util.types.isDate(new Date()); // true
// format — printf uslubida
util.format("%s — %d yosh", "Ali", 19); // "Ali — 19 yosh"
util.promisify2.11-bob — eski callback-asoslangan API'niasync/awaitbilan ishlatish uchun. Lekin ko'p modul (fs/promises) allaqachon promise versiyaga ega — avval shuni qidiring.
2.8. crypto — kriptografiya (xavfsizlik yuragi)
crypto — xavfsizlik amallari (nodejs.org). To'rt asosiy ishlatilishi:
- Tasodifiy ma'lumot (token, ID, tuz) —
randomBytes,randomUUID. - Hash (bir tomonlama) —
createHash(fayl yaxlitligi), parol uchunscrypt/pbkdf2. - HMAC (kalit bilan hash) — imzo (JWT — 5.15).
- Shifrlash (cipher) — ikki tomonlama (kamroq, odatda TLS — 0.4).
2.9. crypto — tasodifiy ma'lumot (token, ID)
import crypto from "node:crypto";
// Tasodifiy bayt → token (sessiya, reset link — 5.15)
crypto.randomBytes(32).toString("hex"); // 64 belgili hex token (0.1: hex)
// UUID — noyob identifikator (zamonaviy, eng oson)
crypto.randomUUID(); // "a3f5b2c1-..." (DB ID uchun)
// Tasodifiy butun son (xavfsiz — Math.random emas!)
crypto.randomInt(1, 100); // 1..99 (OTP, tasodif uchun — 5.18)
Math.random()xavfsizlik uchun EMAS (bashorat qilinadi — 0.6). Token, OTP, parol tuzi uchun doimcrypto(kriptografik xavfsiz tasodif). Bu — xavfsizlik (14) qoidasi.
2.10. crypto — hash (bir tomonlama)
Hash — istalgan ma'lumotni belgilangan uzunlikdagi, qaytarib bo'lmaydigan "barmoq izi"ga aylantirish (3.5: hash funksiya, lekin kriptografik):
// Fayl/ma'lumot yaxlitligi (SHA-256)
const hash = crypto.createHash("sha256").update("ma'lumot").digest("hex");
// Bir xil kirish → doim bir xil hash; ozgina o'zgarsa → butunlay boshqa
// ❌ PAROL uchun SHA-256 ISHLATMANG — juda tez (brute-force oson — 14)
// ✅ PAROL uchun scrypt/bcrypt/argon2 (sekin, tuz bilan — 5.15)Hash vs shifrlash: hash — bir tomonlama (qaytarib bo'lmaydi) — parol, yaxlitlik uchun. Shifrlash — ikki tomonlama (kalit bilan ochiladi) — maxfiy ma'lumot uzatish uchun (0.4: TLS).
2.11. crypto — parol xeshlash (scrypt — 5.15 kirishi)
Parolni hech qachon ochiq saqlamang (14). Uni tuz (salt) bilan, sekin algoritm (scrypt/bcrypt/argon2) orqali xeshlang:
import crypto from "node:crypto";
import { promisify } from "node:util";
const scrypt = promisify(crypto.scrypt); // callback → promise (2.7)
// Parolni xeshlash (ro'yxatdan o'tishda)
async function parolXeshla(parol) {
const tuz = crypto.randomBytes(16).toString("hex"); // har parolga noyob tuz (2.9)
const hosil = await scrypt(parol, tuz, 64); // sekin, CPU-og'ir (5.1: thread pool)
return `${tuz}:${hosil.toString("hex")}`; // tuz + hash birga saqlanadi
}
// Parolni tekshirish (loginda)
async function parolTekshir(parol, saqlangan) {
const [tuz, hash] = saqlangan.split(":");
const hosil = await scrypt(parol, tuz, 64);
return crypto.timingSafeEqual( // timing-safe (14: timing attack)
Buffer.from(hash, "hex"), hosil
);
}Real loyihada
bcrypt/argon2(npm — 5.15) ko'p ishlatiladi (qulayroq), lekin g'oya bir xil: tuz + sekin algoritm + timing-safe taqqoslash.timingSafeEqual— taqqoslash vaqti orqali ma'lumot sizdirmaslik uchun (14).
2.12. crypto — HMAC (imzo)
HMAC — maxfiy kalit bilan hash; ma'lumot buzilmaganini va kimdan kelganini tasdiqlaydi (JWT imzosi — 5.15):
const imzo = crypto.createHmac("sha256", "maxfiy-kalit")
.update("ma'lumot")
.digest("hex");
// Kalitni bilgan kishigina bir xil imzo yaratadi → autentifikatsiya (5.15)2.13. crypto — shifrlash (cipher, ikki tomonlama)
Shifrlash — hash'dan farqli, qaytariladigan (kalit bilan ochiladigan) jarayon 2.10-bob: maxfiy ma'lumotni saqlash/uzatish uchun. Zamonaviy tavsiya — AES-256-GCM (autentifikatsiyalangan, buzilishni ham aniqlaydi):
import crypto from "node:crypto";
const kalit = crypto.randomBytes(32); // 256-bit kalit (xavfsiz saqlanadi — 14)
function shifrla(matn) {
const iv = crypto.randomBytes(12); // har shifrga noyob IV (2.9)
const cipher = crypto.createCipheriv("aes-256-gcm", kalit, iv);
const shifr = Buffer.concat([cipher.update(matn, "utf8"), cipher.final()]);
const tag = cipher.getAuthTag(); // yaxlitlik tegi (GCM)
return { iv, shifr, tag };
}
function ochi({ iv, shifr, tag }) {
const decipher = crypto.createDecipheriv("aes-256-gcm", kalit, iv);
decipher.setAuthTag(tag); // buzilgan bo'lsa — xato (14)
return Buffer.concat([decipher.update(shifr), decipher.final()]).toString("utf8");
}Amalda shifrlash kamroq kerak: maxfiy ma'lumotni odatda umuman saqlamang yoki HTTPS/TLS 0.4-bob uzatadi. Parol — shifrlanmaydi, xeshlanadi 2.11-bob. Kalitni esa kodga yozmang — muhit o'zgaruvchisi/maxfiy do'konda (5.8, 14) saqlang.
2.14. Boshqa foydali core modullar (qisqacha)
import { URL } from "node:url"; // URL parse (0.4, 2.17)
const u = new URL("https://x.com/a?b=1"); // u.pathname, u.searchParams
import { Buffer } from "node:buffer"; // binary ma'lumot (0.1: bayt) — 5.4
import readline from "node:readline"; // terminal kiritish (0.3)
import { exec } from "node:child_process"; // boshqa dastur ishga tushirish (0.2: process)
import { EventEmitter } from "node:events"; // hodisalar (5.4 — keyingi bob)
import { Worker } from "node:worker_threads";// alohida thread (5.1: og'ir CPU)events (EventEmitter) va stream — keyingi bobda 5.4-bob chuqur.
2.15. Atomic File Writes va Crash-Safety (Halokatga chidamli yozish)
Oddiy fs.writeFile("db.json", data) ishlab turgan vaqtda serverda elektr uzilsa yoki Node.js jarayoni OOM (Out Of Memory) sababli SIGKILL olsa, fayl yarimta (chala) yozilgan holda qoladi va uning ichidagi JSON butunlay buziladi (SyntaxError: Unexpected end of JSON input).
Professional yechim — Atomic Write (Atomik yozish):
Ma'lumot avval vaqtinchalik faylga (filename.tmp.UUID) yoziladi va faqat to'liq yozib bo'lingach, POSIX va Windows'da atomik bo'lgan fs.rename orqali asl fayl ustiga ko'chiriladi:
import { writeFile, rename, unlink } from "node:fs/promises";
import path from "node:path";
import crypto from "node:crypto";
async function atomicWriteFile(filePath, content) {
const dir = path.dirname(filePath);
const tempPath = path.join(dir, `.${path.basename(filePath)}.${crypto.randomUUID()}.tmp`);
try {
// 1. Vaqtinchalik faylga to'liq yozib olamiz
await writeFile(tempPath, content, "utf8");
// 2. OS darajasida atomik almashtirish (fayl hech qachon chala qolmaydi)
await rename(tempPath, filePath);
} catch (err) {
// Xatolik yuz bersa, axlat temp faylni tozalaymiz
try { await unlink(tempPath); } catch {}
throw err;
}
}2.16. File Descriptor Leaks va EMFILE: too many open files
Operatsion tizim har bir jarayon bir vaqtning o'zida ayni paytda ochiq tutishi mumkin bo'lgan fayllar soniga cheklov qo'yadi (ulimit -n, odatda 1024 yoki 4096 ta).
Agar past darajadagi fs.open() yoki fs.createReadStream() ishlatilib, fayl deskriptori (FD) yopilmasa, qisqa vaqt ichida backend qulaydi:
Error: EMFILE: too many open files, open '/app/data/user_123.json'Oldini olish qoidalari:
- Doim yuqori darajadagi
readFile/writeFileishlating (ular avtomatik yopadi). - Agar
fs.open()ishlatilsa, doimtry...finallyblokidafileHandle.close()chaqirilishi shart:
import { open } from "node:fs/promises";
let handle;
try {
handle = await open("huge.log", "r");
// O'qish amallari...
} finally {
await handle?.close(); // Har qanday holatda FD yopiladi!
}2.17. Path Traversal (Directory Traversal / Zip Slip) xavfsizlik himoyasi
Foydalanuvchi yuborgan fayl nomini to'g'ridan-to'g'ri path.join bilan birlashtirish — klassik xavfsizlik teshigi (OWASP Top 10):
// ❌ XAVFLI:
// Agar userFileName = "../../../etc/passwd" yoki "..\\..\\Windows\\win.ini" bo'lsa
const target = path.join("/var/www/uploads", req.query.fileName);
// Natija: /etc/passwd o'qib beriladi! Senior Darajadagi Himoya Patterni (path.resolve + Chegara tekshiruvi):
import path from "node:path";
function safeResolvePath(baseDirectory, userInput) {
const safeBase = path.resolve(baseDirectory);
// path.normalize va resolve orqali barcha ../ larni hisoblab chiqamiz
const resolvedTarget = path.resolve(safeBase, userInput);
// Yakuniy yo'l ruxsat etilgan papka bilan boshlanishi shart!
if (!resolvedTarget.startsWith(safeBase + path.sep)) {
throw new Error("Xavfsizlik xatosi: Ruxsat etilmagan yo'lga kirish (Path Traversal)!");
}
return resolvedTarget;
}2.18. Fayllarni kuzatish: fs.watch vs fs.watchFile va nega chokidar
Node.js da fayl yoki papka o'zgarishini kuzatishning ikki yo'li bor:
fs.watchFile(filename, [options], listener)— Stat Polling. Har $N$ millisekundda operatsion tizimdanstatso'rab tekshiradi. Kamchiligi: CPU resursini haddan tashqari ko'p sarflaydi.fs.watch(filename, [options], listener)— OS Kernel Events (Linuxinotify, macOSFSEvents, WindowsReadDirectoryChangesW). Tezkor va resurs tejaydi. Kamchiligi: OS turiga qarab bitta o'zgarish uchun 2-3 marta duplicate event chiqarishi, fayl nomi ba'zidanullqaytishi mumkin.
Sanoat standarti: Katta backend yoki tooling tizimlarida (masalan, Vite, Nodemon, Webpack) to'g'ridan-to'g'ri
fs.watcho'rnigachokidarkutubxonasi ishlatiladi. U OS darajasidagi hodisalarni debouncing, cross-platform normallashtirish va xotira boshqaruvi bilan ta'minlaydi.
2.19. Universal Web Crypto API (globalThis.crypto)
Zamonaviy Node.js (18+) da W3C standarti hisoblangan universal Web Crypto API global obyekti mavjud:
// Hech qanday import shart emas — global ob'ekt!
const id = crypto.randomUUID(); // "4fc911b3-40e1-4560-b6f7-bdf2d0bf7647"
// Brauzer, Cloudflare Workers, Vercel Edge va Node.js da bir xil ishlaydigan hashing:
const encoder = new TextEncoder();
const data = encoder.encode("Salom Dunyo");
const hashBuffer = await crypto.subtle.digest("SHA-256", data);Bu backend kodingizni serverless Edge muhitlarga oson ko'chirish (isomorphic JavaScript) imkonini beradi.
3. Sintaksis — tez ma'lumotnoma
import fs from "node:fs/promises"; // zamonaviy (2.2)
import path from "node:path";
import os from "node:os";
import crypto from "node:crypto";
import { promisify } from "node:util";
// fs (async — server'da)
await fs.readFile(p, "utf8") await fs.writeFile(p, data)
await fs.mkdir(p, {recursive:true}) await fs.readdir(p) await fs.stat(p)
// path (0.2)
path.join(a, b) path.resolve(p) path.basename/dirname/extname(p)
// crypto (14)
crypto.randomUUID() crypto.randomBytes(n).toString("hex")
crypto.createHash("sha256").update(d).digest("hex")
promisify(crypto.scrypt) // parol (5.15)
// os
os.cpus().length os.totalmem() os.tmpdir()4. Batafsil kod namunalari
Misol 1 — fs/promises bilan to'liq CRUD (2.2, 2.3)
import { readFile, writeFile, appendFile, mkdir, readdir, stat } from "node:fs/promises";
import path from "node:path";
async function fileDemo() {
const papka = "data";
await mkdir(papka, { recursive: true }); // papka (0.3: mkdir -p)
const yol = path.join(papka, "users.json"); // OS-mos yo'l (2.5)
// Yozish (JSON — 2.8)
const users = [{ id: 1, ism: "Ali" }];
await writeFile(yol, JSON.stringify(users, null, 2)); // chiroyli JSON
// O'qish
const matn = await readFile(yol, "utf8");
const oqilgan = JSON.parse(matn); // matn → obyekt (2.8)
console.log(oqilgan[0].ism); // "Ali"
// Log qo'shish
await appendFile(path.join(papka, "app.log"), `${new Date().toISOString()} ish bajarildi\n`);
// Papka tarkibi (0.3: ls)
console.log("Fayllar:", await readdir(papka));
console.log("Hajm:", (await stat(yol)).size, "bayt"); // (0.1)
}
fileDemo().catch(console.error); // xato ushlash (2.12)Misol 2 — JSON "ma'lumotlar bazasi" (mini, fs ustida)
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
const DB = path.join(import.meta.dirname, "db.json"); // ESM (2.5)
async function oqi() {
try {
return JSON.parse(await readFile(DB, "utf8")); // (2.8)
} catch (err) {
if (err.code === "ENOENT") return []; // yo'q bo'lsa bo'sh (2.4, 0.2)
throw err; // boshqa xato (2.12)
}
}
async function saqla(data) {
await writeFile(DB, JSON.stringify(data, null, 2));
}
// Qo'shish (immutable — 2.7)
async function userQosh(user) {
const users = await oqi();
const yangi = { id: crypto.randomUUID(), ...user }; // UUID (2.9)
await saqla([...users, yangi]);
return yangi;
}Misol 3 — path bilan rekursiv papka skaneri (0.2 loyihasi qayta)
import { readdir, stat } from "node:fs/promises";
import path from "node:path";
// Papkani rekursiv aylanib, barcha .js fayllarni topish (3.11: rekursiya)
async function jsFayllar(papka) {
const natija = [];
const elementlar = await readdir(papka);
for (const nom of elementlar) {
const toliq = path.join(papka, nom); // (2.5)
const info = await stat(toliq); // (2.3)
if (info.isDirectory()) {
natija.push(...await jsFayllar(toliq)); // rekursiv (3.11)
} else if (path.extname(nom) === ".js") { // (2.5)
natija.push(toliq);
}
}
return natija;
}
console.log(await jsFayllar("./src"));Misol 4 — crypto: token va UUID (2.9)
import crypto from "node:crypto";
// Sessiya tokeni (5.15)
const sessionToken = crypto.randomBytes(32).toString("hex"); // 64 hex belgi (0.1)
// Parol tiklash linki tokeni
const resetToken = crypto.randomBytes(20).toString("base64url");
// DB uchun noyob ID (auto-increment o'rniga — 6)
const userId = crypto.randomUUID(); // "550e8400-e29b-..."
// OTP (6 raqamli — 5.18) — XAVFSIZ tasodif
const otp = crypto.randomInt(100000, 1000000); // 100000..999999 (2.9)
console.log({ sessionToken, userId, otp });Misol 5 — crypto: parol xeshlash (to'liq — 2.11, 5.15)
import crypto from "node:crypto";
import { promisify } from "node:util";
const scrypt = promisify(crypto.scrypt); // (2.7)
export async function hashParol(parol) {
const tuz = crypto.randomBytes(16).toString("hex"); // noyob tuz (2.9)
const hosil = await scrypt(parol, tuz, 64); // sekin (5.1: thread pool)
return `${tuz}:${hosil.toString("hex")}`;
}
export async function tekshirParol(parol, saqlangan) {
const [tuz, hash] = saqlangan.split(":");
const hosil = await scrypt(parol, tuz, 64);
const saqlanganBuf = Buffer.from(hash, "hex");
return saqlanganBuf.length === hosil.length &&
crypto.timingSafeEqual(saqlanganBuf, hosil); // timing-safe (14, 2.11)
}
// Ishlatish
const xesh = await hashParol("MaxfiyParol123");
console.log(await tekshirParol("MaxfiyParol123", xesh)); // true
console.log(await tekshirParol("notogri", xesh)); // falseMisol 6 — crypto: fayl yaxlitligi (hash — 2.10)
import crypto from "node:crypto";
import { readFile } from "node:fs/promises";
// Fayl checksum (yuklab olingan fayl buzilmaganini tekshirish)
async function faylHash(yol) {
const data = await readFile(yol); // Buffer (0.1)
return crypto.createHash("sha256").update(data).digest("hex");
}
const h1 = await faylHash("dastur.zip");
// Agar h1 rasmiy hash bilan bir xil bo'lsa — fayl buzilmagan/o'zgartirilmagan (14)Misol 7 — os: tizim monitoringi (2.6)
import os from "node:os";
function tizimHolati() {
const jami = os.totalmem();
const bosh = os.freemem();
const ishlatilgan = ((jami - bosh) / jami * 100).toFixed(1); // % (0.1)
return {
platforma: os.platform(), // (0.2)
yadrolar: os.cpus().length, // (0.1)
ramJami: (jami / 1024 ** 3).toFixed(2) + " GB", // bayt → GB (0.1)
ramIshlatilgan: ishlatilgan + "%",
uptime: (os.uptime() / 3600).toFixed(1) + " soat",
};
}
console.log(tizimHolati()); // monitoring endpoint uchun (10.9)Misol 8 — util.promisify (eski API → async/await — 2.7)
import { promisify } from "node:util";
import { exec } from "node:child_process";
const execAsync = promisify(exec); // callback → promise (2.11)
// Boshqa dastur (git) ishga tushirish (0.3, 4)
async function gitBranch() {
const { stdout } = await execAsync("git branch --show-current"); // (0.3, 4.2)
return stdout.trim(); // joriy branch nomi
}
console.log("Branch:", await gitBranch());5. To'g'ri va noto'g'ri holatlar
1) Server'da sync (blocking) fs
// ❌ butun serverni to'xtatadi (5.1, 2.2)
const data = fs.readFileSync("katta.txt");
// ✅ async (fs/promises)
const data = await fs.promises.readFile("katta.txt");2) Yo'lni qo'lda yopishtirish
// ❌ Windows'da buziladi (0.2, 2.5)
const yol = papka + "/" + nom;
// ✅ path.join
const yol = path.join(papka, nom);3) Parol uchun SHA-256 / Math.random
// ❌ SHA-256 parol uchun juda tez (brute-force); Math.random bashoratli (14, 2.9, 2.10)
crypto.createHash("sha256").update(parol).digest("hex");
const token = Math.random().toString(36);
// ✅ scrypt/bcrypt (sekin, tuz bilan) + crypto.randomBytes (2.9, 2.11)4) Parol taqqoslashda oddiy ===
// ❌ timing attack xavfi (14)
if (hash === saqlangan) {...}
// ✅ timingSafeEqual (2.11)
crypto.timingSafeEqual(a, b);5) Fayl bormi'ni alohida tekshirib, keyin o'qish
// ❌ race condition (tekshirish va o'qish orasida o'zgarishi mumkin — 2.4)
if (existsSync(p)) { readFile(p); }
// ✅ to'g'ridan o'qib, ENOENT'ni ushlash (2.4, 2.12)
try { await readFile(p); } catch (e) { if (e.code === "ENOENT") {...} }6. Keng tarqalgan xatolar va yechimlari
Xato 1 — ENOENT: no such file or directory
Sababi: fayl/papka yo'q yoki yo'l xato (0.2, 2.4). Yechimi: yo'lni path.join+__dirname bilan to'g'rilang; mkdir {recursive}; xatoni err.code === "ENOENT" bilan ushlang.
Xato 2 — EACCES: permission denied
Sababi: fayl ruxsati (0.2: chmod). Yechimi: ruxsatni to'g'rilang 0.3-bob; o'zingizga tegishli papkada ishlang.
Xato 3 — EISDIR / ENOTDIR
Sababi: fayl o'rnida papka (yoki aksincha — 0.2). Yechimi: stat().isDirectory() bilan tekshiring 2.3-bob.
Xato 4 — [object Object] faylga yozildi
Sababi: obyektni stringifysiz yozish 2.8-bob. Yechimi: JSON.stringify(obj, null, 2).
Xato 5 — crypto callback xatosi (promisify'siz)
Sababi: crypto.scrypt — callback API; to'g'ridan await ishlamaydi (2.7, 2.11). Yechimi: promisify(crypto.scrypt) 2.11-bob.
Xato 6 — require is not defined / __dirname is not defined (ESM'da)
Sababi: ESM'da CommonJS o'zgaruvchilari (2.14, 5.2). Yechimi: import; import.meta.dirname (yangi Node) yoki fileURLToPath(import.meta.url).
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- Node/libuv 5.1-bob: core modullar — libuv ustida; async (thread pool — 5.1).
- Fayl/yo'l/OS 0.2-bob:
fs/path/os— 0.2 tushunchalarining amali. - Xavfsizlik (5.15, 14):
crypto— parol xeshlash, token, HMAC. - Streams 5.4-bob:
fsstream'lari (katta fayl). - File upload 5.11-bob:
fsbilan saqlash;path. - Config 5.8-bob:
fsbilan config o'qish. - Hash Table 3.5-bob: crypto hash — kriptografik versiya.
- Buffer 0.1-bob: binary ma'lumot —
fs/crypto.
8. Eng yaxshi amaliyotlar (best practices)
fs/promises(async/await) ishlating — server'da sync emas (2.2, 5.1).node:prefiks bilan core modul ulang (aniqlik, xavfsizlik — 2.1).- Yo'l uchun
path.join+__dirname/import.meta.dirname(0.2, 2.5). - Parol —
scrypt/bcrypt/argon2(SHA emas — 2.11, 14); tuz + timing-safe. - Token/ID/OTP —
crypto(Math.randomemas — 2.9, 14). - Fayl mavjudligini access bilan emas, o'qib ENOENT ushlang (race condition — 2.4).
- JSON faylga
JSON.stringify(x, null, 2)(o'qishli — 2.8). - Kutubxonadan oldin core modulni qidiring — ko'pincha yetadi 2.7-bob.
- Xatoni
err.codebilan ajrating (ENOENT/EACCES — 0.2, 6-bo'lim).
9. Amaliy loyiha: "Fayl-Asoslangan Mini Backend Vositalari"
Core modullarni amalda mustahkamlash.
Maqsad
fs/promises, path, os, crypto va utilni birlashtirib, fayl-asoslangan, xavfsiz utility'lar to'plamini qurish.
Talablar (requirements)
- JSON DB:
fs/promisesustida mini "ma'lumotlar bazasi" —read,write,add,findById,delete(Misol 2); fayl yo'q bo'lsa bo'sh massiv (ENOENT — 2.4). - UUID ID: har yozuvga
crypto.randomUUID()(Misol 4, 2.9). - Parol moduli:
hashParol/tekshirParol— scrypt + tuz + timingSafeEqual (Misol 5, 2.11). - Token generator: sessiya tokeni, OTP, reset token —
cryptobilan (Misol 4). - Fayl skaneri: rekursiv papka aylanib, kengaytma bo'yicha statistika (Misol 3, 0.2 loyihasi).
- Fayl yaxlitligi: SHA-256 checksum (Misol 6, 2.10).
- Tizim monitoringi:
osbilan platforma/RAM/CPU/uptime (Misol 7). - Log tizimi:
appendFilebilan vaqt belgili log (Misol 1);pathbilan yo'l. - Hammasi async/await (sync yo'q — 2.2); xatolar
err.codebilan boshqarilsin (2.12, 6-bo'lim).
Maslahatlar (hint)
fs/promisesimport qiling; har amalawait2.2-bob.- Yo'l:
path.join(import.meta.dirname, ...)2.5-bob. - Parol:
promisify(crypto.scrypt)(2.7, 2.11); tuz alohida saqlanadi. - Token:
crypto.randomBytes(n).toString("hex"); OTP:crypto.randomInt2.9-bob. - ENOENT:
try/catch+err.code2.4-bob. - JSON:
JSON.stringify(x, null, 2)2.8-bob.
"Tayyor" mezonlari (acceptance criteria)
- JSON DB CRUD ishlaydi (fayl yo'q bo'lsa qulamaydi).
- Har yozuvda UUID.
- Parol scrypt + tuz + timingSafeEqual bilan; to'g'ri/noto'g'ri parol farqlanadi.
- Token/OTP crypto bilan (Math.random emas).
- Fayl skaneri rekursiv, kengaytma statistikasi.
- SHA-256 checksum ishlaydi.
- os monitoringi to'g'ri ma'lumot beradi.
- Hammasi async; xatolar err.code bilan boshqarilgan.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda Node'ning o'rnatilgan kuchli vositalarini — core modullarni chuqur o'rgandik:
- Core modul — npm'siz, darrov mavjud;
node:prefiks bilan ulang. fs— fayl 0.2-bob; uch shakl: sync (server'da emas), callback, promise (zamonaviy); CRUD, stat, mkdir.path— OS-mos yo'l (join/resolve/basename— 0.2); qo'lda yopishtirmang.os— tizim (CPU/RAM/platforma — 0.2); monitoring.util—promisify(callback → Promise — 2.11),inspect.crypto— tasodif (randomBytes/randomUUID/randomInt—Math.randomemas!), hash (createHash; parol uchunscrypt+ tuz + timingSafeEqual), HMAC (imzo — 5.15).
Keyingi bob — 5.4-bob: Events (EventEmitter) va Streams (chuqur). Core modullarni bildik; endi Node'ning ikki kuchli, event-asoslangan tushunchasini — EventEmitter (hodisa chiqarish/tinglash — Node'ning butun arxitekturasi shunga asoslangan) va Streams (katta ma'lumotni xotirani to'ldirmasdan, bo'lak-bo'lak — 0.1) ni chuqur o'rganamiz.
Foydalanilgan rasmiy/ishonchli manbalar
- nodejs.org/api/fs — File system (sync/callback/promises)
- nodejs.org/api/crypto — randomBytes, randomUUID, createHash, scrypt, HMAC, timingSafeEqual
- nodejs.org/api/path, /os, /util — path, os, util.promisify
O'qiganingizni mustahkamlang
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!