Node.js dosyasında __dirname ve ./ arasındaki fark nedir?


498

Node.js'de programlama yaparken ve geçerli dizininizle ilişkili bir yerde bulunan dosyalara referans verirken, __dirnamedeğişkeni normalde kullanmak yerine kullanmak için herhangi bir neden var ./mı? Benim kodunda bugüne kadar ./ kullanarak ve sadece varlığını buldular __dirname, ve esasen benim ./'s dönüştürmek için akıllı olup olmayacağını bilmek istiyorum, ve eğer öyleyse, neden bu akıllı bir fikir olacaktır .


47
tl; dr: Yani, temel olarak, fark './' ve 'process.cwd ()' komut dosyasını çağıran terminalin geçerli dizinini, '__dirname' ise betiğin bulunduğu dizini belirtir. saklanmış.
Gui Imamura

1
.İçinde ne zaman kullanıldığı hariçrequire . İçindeki yol requireher zaman çağrıyı içeren dosyaya göredir require.
Govind Rai

Yanıtlar:


814

Öz

Node.js'de, __dirnameher zaman yürütülmekte olan komut dosyasının bulunduğu dizindir (buna bakın ). Eğer __dirnameiçine yazdıysanız /d1/d2/myscript.js, değer olurdu /d1/d2.

Buna karşılık, ve gibi kütüphaneleri kullandığınızda ., nodekomutu terminal pencerenizde (örneğin çalışma dizininiz) çalıştırdığınız dizini verir . Teknik olarak, çalışma dizininiz olarak başlar, ancak kullanılarak değiştirilebilir .pathfsprocess.chdir()

Bunun istisnası, .ile birlikte kullanmanızdır require(). İçindeki yol requireher zaman çağrıyı içeren dosyaya göredir require.

Örneğin...

Diyelim ki dizin yapınız

/dir1
  /dir2
    pathtest.js

ve pathtest.jsiçerir

var path = require("path");
console.log(". = %s", path.resolve("."));
console.log("__dirname = %s", path.resolve(__dirname));

ve sende yap

cd /dir1/dir2
node pathtest.js

anladın

. = /dir1/dir2
__dirname = /dir1/dir2

Çalışma dizininiz /dir1/dir2böyledir ve çözüm budur .. Yana pathtest.jsbulunan /dir1/dir2şey bu yıllardan __dirnamede giderir için.

Ancak, komut dosyasını /dir1

cd /dir1
node dir2/pathtest.js

anladın

. = /dir1
__dirname = /dir1/dir2

Bu durumda, çalışma dizini oldu /dir1en neyi böylece .karar, ama __dirnameyine de giderir için /dir1/dir2.

.İçinde kullanma require...

İçeride ise dir2/pathtest.jsbir var requireiçine çağrıyı içinde bir dosya eklemek dir1, olur hep yapmak

require('../thefile')

çünkü içindeki yol requireher zaman aradığınız dosyaya göredir. Çalışma dizininizle hiçbir ilgisi yoktur.


38
IMO, bu açıklama kabul edilen cevaptan biraz daha açıktır (bilirsiniz, "mevcut dizin" biraz belirsizdir).
enkarne

5
Katılıyorum. Kabul edilen cevabı değiştireceğim. Lütfen bu cevabın orijinal cevabın kabul edilmesinden 2.5 yıl sonra eklendiğini ve sadece şimdi fark ettim (2 yıl sonra). :) Geç olsun güç olmasın!
thisissami

14
Her zaman düğümün başlatıldığı dizin ./olmadığını belirtmek gerekir . Bu şekilde başlar, ancak üzerinden değiştirilebilir . Yani, kodunuz çalışma dizinini açıkça değiştirmedikçe, her zaman geçerli çalışma dizini, genellikle dizin düğümü başlatıldı. process.chdir()./
gilly3

3
Kullanma konusunda biraz kafam karıştı. iç kısım gerektirir, eğer içerideki yol her zaman aradığınız dosyayla göreceli ise, yol istemek yerine '(' ../ dir1 / dosya ') gerekli değil (' ../ thefile ') olmalıdır? Düşündüm .. zaten mevcut pozisyon dir2 bir dir1 bir seviyeye geri getirmek. Hala dir1 yoluna koymanız gerekiyor mu yoksa bir şeyi anladım mı?
andromada

1
../someDirBazı komut dosyalarında kullanmanız gerekiyorsa ve komutu farklı bir klasörden çalıştıracaksanız ne yapardınız ?
cbdeveloper

154

./require()işlevi dışında geçerli çalışma dizinini ifade eder . Kullanırken require(), ./çağrılan geçerli dosyanın dizinine çevirir . __dirnameher zaman geçerli dosyanın dizinidir.

Örneğin, aşağıdaki dosya yapısıyla

/home/user/dir/files/config.json

{
  "hello": "world"
}

/home/user/dir/files/somefile.txt

text file

/home/user/dir/dir.js

var fs = require('fs');

console.log(require('./files/config.json'));
console.log(fs.readFileSync('./files/somefile.txt', 'utf8'));

Ben ise cdiçine /home/user/dirve çalıştırmak node dir.jsalacağım

{ hello: 'world' }
text file

Ama aynı komut dosyası çalıştırdığınızda /home/user/I get

{ hello: 'world' }

Error: ENOENT, no such file or directory './files/somefile.txt'
    at Object.openSync (fs.js:228:18)
    at Object.readFileSync (fs.js:119:15)
    at Object.<anonymous> (/home/user/dir/dir.js:4:16)
    at Module._compile (module.js:432:26)
    at Object..js (module.js:450:10)
    at Module.load (module.js:351:31)
    at Function._load (module.js:310:12)
    at Array.0 (module.js:470:10)
    at EventEmitter._tickCallback (node.js:192:40)

Kullanma ile ./çalıştı requireama değil fs.readFileSync. Bunun için çünkü var fs.readFileSync, ./(bu durumda CWD'sindeki çevirir /home/user/). Ve /home/user/files/somefile.txtyok.


oh __dirname'in şu anki çalışma dizini olduğunu düşündüm ... açıklama için teşekkürler!
thisissami

Uygulamanın çalışma dizinine fs ile başvurmanın herhangi bir yolu var mı? Örneğin, çalışma dizininden bir dosya yüklemeye çalışıyorum /movies, ancak /custom_modules/__dirname/custom_modules/movies

2
Sen kullanabilir ./ya process.cwd(). bkz. nodejs.org/api/process.html#process_process_cwd
fent

Gerekir ifadelerinde __dirname üzerinde ./ kullanmanın iyi bir fikir olmadığını belirtmek gerekir, çünkü düğümde aynı şekilde davransalar da, başka türlü kolayca önlenebilecek paketler için browserify derlemeleri ile ilgili sorunlara neden olabilirler.
Jed Watson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.