नोड.जेएस में __dirname और ./ के बीच क्या अंतर है?


497

जब Node.js में प्रोग्रामिंग करते हैं और फ़ाइलों को संदर्भित करते हैं जो आपकी वर्तमान निर्देशिका के संबंध में कहीं स्थित हैं, तो क्या __dirnameकेवल एक नियमित के बजाय चर का उपयोग करने का कोई कारण है ./? मैं उपयोग कर रहा हूं। / इस प्रकार अपने कोड में और अभी के अस्तित्व की खोज की है __dirname, और अनिवार्य रूप से जानना चाहता हूं कि क्या यह मेरे / ./ को परिवर्तित करने के लिए स्मार्ट होगा, और यदि हां, तो यह एक स्मार्ट विचार क्यों होगा। ।


47
tl; dr: तो, मूल रूप से, अंतर यह है कि './' और 'process.cwd ()' स्क्रिप्ट को कॉल करने वाले टर्मिनल के वर्तमान डायर को संदर्भित करता है, जबकि '__dirname' का संदर्भ उस dir से है जिसमें स्क्रिप्ट है संग्रहीत।
गुई इमामुरा

1
सिवाय इसके कि .अंदर कब इस्तेमाल किया जाए require। अंदर requireका रास्ता हमेशा उस फाइल के सापेक्ष होता है जिसमें कॉल होती है require
गोविंद राय

जवाबों:


813

सार

Node.js में, __dirnameहमेशा वह निर्देशिका होती है जिसमें वर्तमान में निष्पादित स्क्रिप्ट रहती है (इसे देखें )। इसलिए यदि आप टाइप __dirnameकरते हैं /d1/d2/myscript.js, तो मान होगा /d1/d2

इसके विपरीत, .आप निर्देशिका जिसमें से आप भाग गया देता है nodeअपने टर्मिनल विंडो में आदेश (यानी अपने कार्यशील निर्देशिका) जब आप की तरह पुस्तकालयों का उपयोग pathऔर fs। तकनीकी रूप से, यह आपकी कार्यशील निर्देशिका के रूप में शुरू होता है, लेकिन इसका उपयोग करके बदला जा सकता है process.chdir()

अपवाद तब होता है जब आप उपयोग .करते हैं require()। अंदर requireका रास्ता हमेशा उस फाइल के सापेक्ष होता है जिसमें कॉल होती है require

उदाहरण के लिए...

मान लीजिए कि आपकी निर्देशिका संरचना है

/dir1
  /dir2
    pathtest.js

और pathtest.jsइसमें शामिल है

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

और आप करते हैं

cd /dir1/dir2
node pathtest.js

आपको मिला

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

आपकी वर्किंग डाइरेक्टरी /dir1/dir2इतनी है कि इसका .समाधान क्या है। चूँकि उसमें pathtest.jsस्थित है और /dir1/dir2जो __dirnameजैसा है वैसा ही हल करता है।

हालाँकि, यदि आप स्क्रिप्ट से चलाते हैं /dir1

cd /dir1
node dir2/pathtest.js

आपको मिला

. = /dir1
__dirname = /dir1/dir2

उस स्थिति में, आपकी कार्यशील निर्देशिका /dir1इतनी थी कि उसका .समाधान किया गया था, लेकिन फिर __dirnameभी वह हल करता है /dir1/dir2

.अंदर का उपयोग require...

अंदर तो dir2/pathtest.jsआप एक है requireमें कॉल एक फ़ाइल को शामिल अंदर dir1आप चाहते हैं हमेशा करना

require('../thefile')

क्योंकि अंदर requireका पथ हमेशा उस फ़ाइल के सापेक्ष होता है जिसमें आप उसे कॉल कर रहे हैं। इसका आपके वर्किंग डायरेक्टरी से कोई लेना-देना नहीं है।


38
IMO, यह स्पष्टीकरण स्वीकृत उत्तर से एक की तुलना में थोड़ा स्पष्ट है (आप जानते हैं, "वर्तमान निर्देशिका" थोड़ा अस्पष्ट है)।
अवतार लें

5
मैं सहमत हूँ। मैं स्वीकृत उत्तर को बदल दूंगा। कृपया ध्यान रखें कि मूल उत्तर स्वीकार किए जाने के 2.5 साल बाद यह उत्तर जोड़ा गया था, और मैंने केवल इसे अभी देखा है (2 साल बाद दूसरा)। :) देर आए दुरुस्त आए!
Thisissami

14
यह है कि ध्यान देने योग्य ./नहीं है हमेशा निर्देशिका उस नोड से शुरू किया गया था। यह उस तरह से शुरू होता है, लेकिन के माध्यम से बदला जा सकता है process.chdir()। इसलिए, ./हमेशा वर्तमान कामकाजी निर्देशिका है, जो आमतौर पर निर्देशिका नोड से लॉन्च किया गया था, जब तक कि आपके कोड ने स्पष्ट रूप से कार्यशील निर्देशिका को बदल नहीं दिया।
gilly3

3
मैं प्रयोग के बारे में थोड़ा भ्रमित हूँ। अंदर के हिस्से की आवश्यकता होती है, यदि आपके अंदर की आवश्यकता का रास्ता हमेशा उस फ़ाइल के सापेक्ष होता है जिसे आप कॉल कर रहे हैं, तो क्या आवश्यकता के बजाय ('../ thefile') पथ की आवश्यकता नहीं होनी चाहिए ('../ dir1 / thefile')? मुझे लगा कि .. रास्ते की वर्तमान स्थिति को dir2 से dir1 में पहले से ही एक स्तर वापस लाएं। क्या आपको अभी भी रास्ते में dir1 लगाने की ज़रूरत है या क्या मुझे कुछ समझ में आ रहा है?
andromada

1
और अगर आपको ../someDirकिसी स्क्रिप्ट में उपयोग करने की आवश्यकता है और आप एक अलग फ़ोल्डर से कमांड चलाने जा रहे हैं तो आप कैसे करेंगे ?
cbdeveloper

154

./require()फ़ंक्शन को छोड़कर, वर्तमान कार्य निर्देशिका को संदर्भित करता है । उपयोग करते समय require(), यह ./वर्तमान फ़ाइल की निर्देशिका में अनुवाद करता है जिसे कहा जाता है। __dirnameहमेशा वर्तमान फ़ाइल की निर्देशिका है।

उदाहरण के लिए, निम्न फ़ाइल संरचना के साथ

/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'));

अगर मैं cdमें /home/user/dirऔर चलाने node dir.jsमैं मिल जाएगा

{ hello: 'world' }
text file

लेकिन जब मैं वही स्क्रिप्ट चलाता हूं तो /home/user/मुझे मिलता है

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

का उपयोग कर ./के साथ काम किया है, requireलेकिन के लिए नहीं fs.readFileSync। ऐसा इसलिए है fs.readFileSync, क्योंकि ./cwd में अनुवाद किया जाता है (इस मामले में /home/user/)। और /home/user/files/somefile.txtमौजूद नहीं है।


ओह, मैंने सोचा था कि __dirname वर्तमान कार्यशील निर्देशिका थी ... स्पष्टीकरण के लिए धन्यवाद!
दिसिस्वामी

क्या एफएस के साथ ऐप की कामकाजी निर्देशिका को संदर्भित करने का कोई तरीका है? उदाहरण के लिए, मैं एक फाइल को वर्किंग डायरेक्टरी से लोड करने की कोशिश कर रहा हूं /movies, लेकिन चूंकि मेरा मॉड्यूल किसी फाइल में है /custom_modules/, __dirnameइसलिए मूवी को हथियाने की कोशिश करता है,/custom_modules/movies

2
आप उपयोग कर सकते हैं ./या process.cwd()। देख nodejs.org/api/process.html#process_process_cwd
fent

वर्थ नोटिंग यह __dirname ओवर ./ का उपयोग करने के लिए एक अच्छा विचार नहीं है। बयानों की आवश्यकता होती है क्योंकि यद्यपि वे नोड में समान रूप से व्यवहार करते हैं, यह उन ब्राउज़र के साथ समस्याएँ पैदा कर सकता है जो आसानी से अन्यथा बच जाते हैं।
जेड वॉटसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.