path.join() yol parçalarını doğru ayırıcıyla birleştirir, .. ifadelerini ve tekrarlanan slash'ları temizler, ama relative bir parçayla başladıysan sonucu relative bırakır. path.resolve() aynı işi sağdan sola yapar ve her zaman mutlak bir yol döndürür: geçerli çalışma klasöründen başlar ve yol boyunca karşılaştığı her mutlak parça yolu baştan başlatır. Bir yol oluşturmak için join, mutlak bir yola ihtiyacın olduğunda resolve kullan.
Program users/ada/notes.txt, ardından users/grace/todo.txt (.., ada'yı sildi), sonra /srv/app/public/index.html ve src/lib/utils.js yazdırdı: fazla slash'lar ve boş parçalar gitti. join, /public/'i asla yeni bir başlangıç saymaz; o sadece sıradaki parçadır.
path.join ve path.resolve farkı
Fark, bir parça / ile başladığında ya da ilk parça relative olduğunda ortaya çıkar:
Ortada /public varken join /srv/app/public/img üretti, resolve ise ondan öncekileri atıp /public/img üretti; ..'yı ikisi de aynı şekilde işledi. Son iki satır, join'in public/index.html'i relative bıraktığını, resolve'un ise başına geçerli klasörü koyarak onu mutlak yaptığını gösteriyor.
path.join | path.resolve | |
|---|---|---|
| Sonuç | Girdi gibi relative ya da mutlak | Her zaman mutlak |
/ ile başlayan bir parça | Sıradan bir parça | Yolu oradan baştan başlatır |
| Başlangıç noktası | Yok | Geçerli çalışma klasörü |
| Argüman yoksa | '.' | Geçerli çalışma klasörü |
| Tipik kullanım | Parçalardan yol oluşturmak | Kullanıcı girdisini ya da config'i mutlak bir yola çevirmek |
basename, dirname, extname ve parse
Bunlar bir yolu parçalarına ayırır. Yalnızca string'e bakarlar: dosyanın var olması gerekmez.
Program cat.final.jpg, cat.final, /home/ada/photos ve .jpg yazdırdı: extname yalnızca son noktadan sonraki kısmı alır. path.parse hepsini birden döndürür (root, dir, base, ext, name), path.format da böyle bir nesneyi tekrar string'e çevirir.
__dirname ve __filename
Bir CommonJS dosyasında __dirname, dosyayı içeren klasörün mutlak yoludur, __filename ise dosyanın kendisinin. 'data.json' gibi relative bir yol, kullanıcının node'u nereden çalıştırdığına göre çözülür ve biri script'ini başka bir klasörden başlattığı anda bozulur. Yolları bunun yerine __dirname'den oluştur:
Program config.json dark ve index.js yazdırdı. Tam yollar her makinede farklıdır; onları elle yazmak yerine path.join(__dirname, ...) ile oluşturmanın nedeni tam olarak budur.
ES modules'te __dirname: import.meta.dirname
ES modules'te __dirname yoktur; kullanmak ReferenceError: __dirname is not defined in ES module scope hatası fırlatır. Node.js 20.11'den beri onların yerini import.meta.dirname ve import.meta.filename alır:
Program index.js ve data/users.json yazdırdı. 20.11'den eski Node.js sürümlerinde klasörü modül URL'sinden türet: path.dirname(fileURLToPath(import.meta.url)), fileURLToPath de node:url'den gelir.
Yolları neden string ile birleştirmemeli
'data' + '/' + file macOS ve Linux'ta çalışır, sonra ayırıcının \ olduğu Windows'ta bozulur; ayrıca .., çift slash ya da eksik slash için hiçbir şey yapmaz. path üzerinde çalıştığı sistemin kurallarını kullanır. Windows sonucunu herhangi bir makineden path.win32 ile görebilirsin:
const path = require('path');
path.posix.join('users', 'ada', 'notes.txt'); // 'users/ada/notes.txt'
path.win32.join('users', 'ada', 'notes.txt'); // 'users\\ada\\notes.txt'
path.sep; // '/' on macOS and Linux, '\\' on Windows
path.join'in sonucunu fs.readFile'a ver, aynı kod dosyayı her sistemde okur.
Sık yapılan hatalar
extname'in çift uzantıları bilmesini beklemek. path.extname('archive.tar.gz') sonucu '.gz''dir; .env gibi noktayla başlayan bir dosyanın ise hiç uzantısı yoktur: path.extname('.env') sonucu '''dir. Tüm son ek önemliyse ismin sonunu kendin kontrol et.
Bir kullanıcıyı klasör içinde tutmak için join'e güvenmek. path.join('/srv/app', '../../etc/passwd') sonucu '/etc/passwd''dir. Bir isteğin adını verdiği bir dosyayı okumadan önce yolu resolve et ve hâlâ kendi klasörünle başladığını kontrol et.
Sıkça Sorulan Sorular
__dirname ile process.cwd() arasındaki fark nedir?
__dirname geçerli kaynak dosyanın klasörüdür ve hiç değişmez. process.cwd() ise kullanıcının node'u çalıştırdığı klasördür. İkisi yalnızca program kendi klasöründen başlatıldığında aynıdır.
__dirname ile path.join mi kullanmalıyım, path.resolve mu?
path.join(__dirname, 'data.json') için ikisi de çalışır, çünkü __dirname zaten mutlaktır. Bir parçanın kendisi de mutlak olabiliyorsa, örneğin kullanıcının yazdığı bir yolsa, ve o yolun geçerli olmasını istiyorsan resolve kullan.
path modülünü URL'lerle nasıl kullanırım?
Kullanma: URL'ler her zaman / kullanır ve .. ile query string'ler için kendi kuralları vardır. new URL('../img/logo.png', 'https://example.com/docs/page') örneğindeki gibi URL class'ını kullan.