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.