Node.js path moduli va papkalar

fs darsida faylni nomi bilan ochdingiz: readFileSync("notes.txt"). Papka boshqa joyda bo’lsa-chi? Yoki kod Windows’da yozilib, serverda Linux’da ishlasa-chi? Yo’lni qo’lda yig’ish aynan shu yerda buziladi. path moduli shu ishni to’g’ri bajaradi.

Muammo: yo’l ajratuvchisi har tizimda boshqacha

Operatsion tizimlar papkalarni turlicha ajratadi:

Tizim Ajratuvchi Misol
Windows \ data\users\list.json
macOS, Linux / data/users/list.json

Yo’lni qo’lda birlashtirsangiz, bitta tizimga bog’lanib qolasiz:

// Bunday yozmang
const filePath = "data/" + "users" + "/list.json";

console.log(filePath);
data/users/list.json

Bu Linux’da ishlaydi. Windows’da ham ko’p holatda ishlaydi, lekin chegaraviy holatlarda buziladi: ikkita chiziq qo’shilib ketsa (data//users) yoki foydalanuvchi kiritgan qism / bilan tugasa.

path.join — to’g’ri yechim

const path = require("path");

const filePath = path.join("data", "users", "list.json");

console.log(filePath);

Windows’da:

data\users\list.json

macOS va Linux’da:

data/users/list.json

Bitta kod, har tizimda to’g’ri natija. path.join ajratuvchini o’zi tanlaydi.

path.join ortiqcha belgilarni ham tozalaydi:

const path = require("path");

console.log(path.join("data", "reports", "..", "list.json"));
data\list.json

.. bir papka yuqoriga ko’taradi — join buni hisobga olib yo’lni qisqartirdi.

path.resolve — to’liq yo’l

join bo’laklarni ulaydi. resolve esa to’liq yo’l qaytaradi:

const path = require("path");

console.log("join:   ", path.join("data", "list.json"));
console.log("resolve:", path.resolve("data", "list.json"));
join:    data\list.json
resolve: D:\node-start\data\list.json
Metod Natija Qachon
path.join Bo’laklarni ulaydi Yo’l qismlarini birlashtirish
path.resolve To’liq yo’l beradi Aniq manzil kerak bo’lganda

resolve hisoblashda joriy ishchi papka dan boshlaydi — pastda shuning tuzog’ini ko’ramiz.

__dirname bilan ishonchli yo’l

Modul tizimi darsida __dirname bilan tanishgansiz: u fayl turgan papkaning to’liq yo’lini beradi.

Nega bu muhim? Chunki node buyrug’ini qayerdan berganingizga qarab natija o’zgaradi.

read-config.js faylini node-start papkasiga qo’ying:

const fs = require("fs");
const path = require("path");

// Fayl shu skript turgan papkadan qidiriladi
const configPath = path.join(__dirname, "config.json");

console.log("Qidirilayotgan yo'l:", configPath);

if (fs.existsSync(configPath)) {
  const content = fs.readFileSync(configPath, "utf8");
  console.log("Sozlama o'qildi:", JSON.parse(content).appName);
} else {
  console.log("Sozlama fayli topilmadi");
}

Yoniga config.json yarating:

{
  "appName": "Test dastur"
}

Endi skriptni boshqa papkadan ishga tushiring:

cd ..
node node-start/read-config.js
Qidirilayotgan yo'l: D:\node-start\config.json
Sozlama o'qildi: Test dastur

__dirname ishlatilgani uchun fayl topildi. Agar kodda shunchaki "config.json" yozilganda bo’lsa, Node.js uni joriy papkadan qidirar va ENOENT chiqar edi.

Yo’lni bo’laklarga ajratish

path yo’ldan kerakli qismni ajratib beradi:

const path = require("path");

const filePath = "/home/app/report.txt";

console.log("extname: ", path.extname(filePath));
console.log("basename:", path.basename(filePath));
console.log("dirname: ", path.dirname(filePath));
extname:  .txt
basename: report.txt
dirname:  /home/app
Metod Nimani beradi
path.extname Kengaytma, nuqtasi bilan
path.basename Fayl nomi
path.dirname Fayl turgan papka

basename ga ikkinchi argument berilsa, kengaytmani olib tashlaydi:

const path = require("path");

console.log(path.basename("/home/app/report.txt", ".txt"));
report

Hammasini birdan olish uchun path.parse bor:

const path = require("path");

console.log(path.parse("/home/app/report.txt"));
{
  root: '/',
  dir: '/home/app',
  base: 'report.txt',
  ext: '.txt',
  name: 'report'
}

Papka ichini o’qish

fs.readdirSync papkadagi fayl nomlarini massiv qilib qaytaradi:

const fs = require("fs");
const path = require("path");

const folderPath = __dirname;
const entries = fs.readdirSync(folderPath);

console.log("Jami:", entries.length);
console.log(entries);
Jami: 5
[ 'app.js', 'config.json', 'math.js', 'notes.txt', 'read-config.js' ]

Faqat .js fayllarni ajratish uchun extname bilan birlashtiramiz:

const fs = require("fs");
const path = require("path");

const entries = fs.readdirSync(__dirname);

const scripts = entries.filter((entry) => path.extname(entry) === ".js");

console.log("JavaScript fayllar:");
scripts.forEach((script) => {
  console.log("-", path.basename(script, ".js"));
});
JavaScript fayllar:
- app
- math
- read-config

Massiv metodlari darsidagi filter va forEach shu yerda ishga tushdi.

Fayl yoki papka ekanini aniqlash

readdirSync nom qaytaradi, lekin u fayl yoki papka ekanini aytmaydi. Buning uchun statSync kerak:

const fs = require("fs");
const path = require("path");

const entries = fs.readdirSync(__dirname);

entries.forEach((entry) => {
  const fullPath = path.join(__dirname, entry);
  const info = fs.statSync(fullPath);
  const label = info.isDirectory() ? "papka" : "fayl";

  console.log(`${entry} — ${label}, ${info.size} bayt`);
});
app.js — fayl, 210 bayt
config.json — fayl, 32 bayt
data — papka, 4096 bayt
notes.txt — fayl, 29 bayt

statSync ga to’liq yo’l berilishiga e’tibor bering. Faqat nom berilganda yana o’sha ENOENT chiqadi.

Papka yaratish

const fs = require("fs");
const path = require("path");

const dataPath = path.join(__dirname, "data", "reports");

// recursive: oraliq papkalarni ham yaratadi
fs.mkdirSync(dataPath, { recursive: true });

console.log("Papka tayyor:", dataPath);
Papka tayyor: D:\node-start\data\reports

{ recursive: true } ikki foyda beradi: data papkasi bo’lmasa ham yaratadi va papka allaqachon mavjud bo’lsa xato bermaydi.

ES modulda __dirname o’rniga

"type": "module" qo’yilgan loyihada __dirname mavjud emas. O’rniga import.meta.url ishlatiladi:

import path from "path";
import { fileURLToPath } from "url";

const currentFile = fileURLToPath(import.meta.url);
const currentDir = path.dirname(currentFile);

console.log("Papka:", currentDir);
Papka: D:\node-start

import.meta.url yo’lni file:///D:/node-start/app.js ko’rinishida beradi, fileURLToPath esa uni oddiy yo’lga aylantiradi.

Biz CommonJS ishlatayotganimiz uchun __dirname yetarli — bu yozuv ES modulli loyihaga tushganingizda kerak bo’ladi.

Amaliy mashq

node-start papkasida bajaring:

  1. path.join bilan uch bo’lakdan yo’l yig’ing va natijani chiqaring — tizimingiz qaysi ajratuvchini qo’yganini ko’ring;
  2. Bir xil bo’laklar uchun path.join va path.resolve natijalarini yonma-yon chiqarib, farqini yozib qo’ying;
  3. read-config.js ni yozib, uni avval o’z papkasidan, keyin bir papka yuqoridan ishga tushiring — __dirname tufayli natija o’zgarmaydi;
  4. Koddagi path.join(__dirname, "config.json") ni shunchaki "config.json" ga almashtiring va yuqori papkadan ishga tushirib ENOENT ni ko’ring, so’ng orqaga qaytaring;
  5. readdirSync bilan papkadagi fayllarni sanang va faqat .json kengaytmalilarini ajrating;
  6. statSync bilan har element fayl yoki papka ekanini va hajmini chiqaring.

4-qadam eng muhimi: __dirname nega kerakligini tushuntirib o’tirmay, to’g’ridan-to’g’ri ko’rsatadi.

Qisqacha xulosa

  • Yo’l ajratuvchisi Windows’da \, Linux va macOS’da / — qo’lda birlashtirish shuning uchun ishonchsiz.
  • path.join bo’laklarni ulaydi va ajratuvchini tizimga qarab tanlaydi.
  • path.resolve to’liq yo’l qaytaradi, join esa nisbiy qoldiradi.
  • Dastur o’z faylini o’qiyotganda yo’l path.join(__dirname, ...) bilan yig’iladi — aks holda natija terminal qayerdan ochilganiga bog’liq bo’lib qoladi.
  • extname, basename, dirname yo’ldan kerakli qismni ajratadi.
  • fs.readdirSync papkadagi nomlarni beradi, statSync esa ular haqida ma’lumot.
  • ES modulda __dirname o’rniga import.meta.url va fileURLToPath ishlatiladi.

Keyingi darsda process va argumentlar — dasturga terminaldan ma’lumot uzatish.

Bu dars foydali bo'ldimi?

marta ko'rildi