IlmHamroh
Dasturlash kitobi (eski nashr)/5-QISM — Nodejs3/23-dars20 daqiqa
Mundarija (42)

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 — crypto ustida.
  • 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):

js
// 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):

text
  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)
js
// 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)

js
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)

js
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:

js
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. Doim path.join. __dirname/import.meta.dirname bilan — fayl joyiga nisbatan ishonchli yo'l.

2.6. os — operatsion tizim ma'lumoti (0.2)

js
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):

js
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.promisify 2.11-bob — eski callback-asoslangan API'ni async/await bilan 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:

  1. Tasodifiy ma'lumot (token, ID, tuz) — randomBytes, randomUUID.
  2. Hash (bir tomonlama) — createHash (fayl yaxlitligi), parol uchun scrypt/pbkdf2.
  3. HMAC (kalit bilan hash) — imzo (JWT — 5.15).
  4. Shifrlash (cipher) — ikki tomonlama (kamroq, odatda TLS — 0.4).

2.9. crypto — tasodifiy ma'lumot (token, ID)

js
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 doim crypto (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):

js
// 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:

js
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):

js
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):

js
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)

js
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:

js
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:

text
Error: EMFILE: too many open files, open '/app/data/user_123.json'

Oldini olish qoidalari:

  1. Doim yuqori darajadagi readFile / writeFile ishlating (ular avtomatik yopadi).
  2. Agar fs.open() ishlatilsa, doim try...finally blokida fileHandle.close() chaqirilishi shart:
js
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):

js
// ❌ 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):

js
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:

  1. fs.watchFile(filename, [options], listener) — Stat Polling. Har $N$ millisekundda operatsion tizimdan stat so'rab tekshiradi. Kamchiligi: CPU resursini haddan tashqari ko'p sarflaydi.
  2. fs.watch(filename, [options], listener) — OS Kernel Events (Linux inotify, macOS FSEvents, Windows ReadDirectoryChangesW). Tezkor va resurs tejaydi. Kamchiligi: OS turiga qarab bitta o'zgarish uchun 2-3 marta duplicate event chiqarishi, fayl nomi ba'zida null qaytishi mumkin.

Sanoat standarti: Katta backend yoki tooling tizimlarida (masalan, Vite, Nodemon, Webpack) to'g'ridan-to'g'ri fs.watch o'rniga chokidar kutubxonasi 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:

js
// 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

js
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)

js
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)

js
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)

js
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)

js
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)

js
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));          // false

Misol 6 — crypto: fayl yaxlitligi (hash — 2.10)

js
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)

js
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)

js
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

js
// ❌ 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

js
// ❌ 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

js
// ❌ 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 ===

js
// ❌ timing attack xavfi (14)
if (hash === saqlangan) {...}

// ✅ timingSafeEqual (2.11)
crypto.timingSafeEqual(a, b);

5) Fayl bormi'ni alohida tekshirib, keyin o'qish

js
// ❌ 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: fs stream'lari (katta fayl).
  • File upload 5.11-bob: fs bilan saqlash; path.
  • Config 5.8-bob: fs bilan 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.random emas — 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.code bilan 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)

  1. JSON DB: fs/promises ustida mini "ma'lumotlar bazasi" — read, write, add, findById, delete (Misol 2); fayl yo'q bo'lsa bo'sh massiv (ENOENT — 2.4).
  2. UUID ID: har yozuvga crypto.randomUUID() (Misol 4, 2.9).
  3. Parol moduli: hashParol/tekshirParol — scrypt + tuz + timingSafeEqual (Misol 5, 2.11).
  4. Token generator: sessiya tokeni, OTP, reset token — crypto bilan (Misol 4).
  5. Fayl skaneri: rekursiv papka aylanib, kengaytma bo'yicha statistika (Misol 3, 0.2 loyihasi).
  6. Fayl yaxlitligi: SHA-256 checksum (Misol 6, 2.10).
  7. Tizim monitoringi: os bilan platforma/RAM/CPU/uptime (Misol 7).
  8. Log tizimi: appendFile bilan vaqt belgili log (Misol 1); path bilan yo'l.
  9. Hammasi async/await (sync yo'q — 2.2); xatolar err.code bilan boshqarilsin (2.12, 6-bo'lim).

Maslahatlar (hint)

  • fs/promises import qiling; har amal await 2.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.randomInt 2.9-bob.
  • ENOENT: try/catch + err.code 2.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.random emas!), hash (createHash; parol uchun scrypt + 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
Ulashish:Telegram'da

O'qiganingizni mustahkamlang

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.3-bob: Core modullar — fs, path, os, util, crypto — IlmHamroh