2012-10-24 19 views
12

में अनुप्रयोग रूट के सापेक्ष फ़ाइलों को संदर्भित करने का उचित तरीका मेरे पास एक Node.JS एप्लिकेशन है जो एडब्ल्यूएस ईसी 2 पर लिनक्स पर चल रहा है जो HTML टेम्पलेट फ़ाइलों में पढ़ने के लिए fs मॉड्यूल का उपयोग करता है।Node.JS

/server.js 
/templates/my-template.html 
/services/template-reading-service.js 

एचटीएमएल टेम्पलेट्स हमेशा उस स्थान में हो जाएगा, हालांकि, टेम्पलेट पढ़ने-सेवा भर के विभिन्न स्थानों में जा सकते हैं (गहरी उपनिर्देशिका, आदि) के भीतर से: यहाँ आवेदन की वर्तमान संरचना है टेम्पलेट पढ़ने-सेवा मैं तो जैसे फ़ाइल को लोड करने, fs.readFileSync() का उपयोग करें:

Error: ENOENT, no such file or directory './templates/my-template.html' 

मैं था संभालने हूँ:

var templateContent = fs.readFileSync('./templates/my-template.html', 'utf8'); 

यह निम्न त्रुटि फेंकता टी इसलिए है क्योंकि पथ './' '/ services /' निर्देशिका में हल हो रहा है, न कि अनुप्रयोग रूट। मैंने '../templates/my-template.html' के पथ को बदलने का भी प्रयास किया है और यह काम करता है, लेकिन यह भंगुर लगता है क्योंकि मुझे लगता है कि 'केवल एक निर्देशिका' के सापेक्ष हल हो रहा है। यदि मैं टेम्पलेट-रीडिंग-सेवा को गहरी उपनिर्देशिका में ले जाता हूं, तो वह पथ टूट जाएगा।

तो, आवेदन की जड़ से संबंधित फ़ाइलों का संदर्भ देने का सही तरीका क्या है?

उत्तर

15

var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8'); 
+2

क्या वास्तव में __dirname वर्तमान स्क्रिप्ट/मॉड्यूल कहां है? तो मेरे उदाहरण में, 'टेम्पलेट-रीडिंग-सर्विस' के भीतर से निष्पादित करते समय।जेएस '__dirname'/सेवाओं/'को हल नहीं करेगा? – user1438940

+0

@ user1438940 मैंने सोचा कि आप '/ server.js' में फ़ाइल पढ़ने कोड निष्पादित करते हैं। "../templates/my-template.html" – InspiredJW

+0

नहीं आज़माएं, fs.getFileSync निष्पादित कोड "टेम्पलेट-रीडिंग-service.js" में है। मैं "../" का उपयोग नहीं करना चाहता; यह मेरे प्रश्न का पूरा बिंदु है। अगर मैं "../" का उपयोग करता हूं और बाद में मैं "/ services /" निर्देशिका से "टेम्पलेट-रीडिंग-सर्विस.जेएस" को "/ services/templating /" पर ले जाता हूं तो मेरे सभी कोड ब्रेक होते हैं। या, यदि मैं वैश्विक कॉन्फ़िगरेशन में सेटिंग के रूप में टेम्पलेट निर्देशिका का पथ रखना चाहता हूं, तो इसका उपयोग 20 अलग-अलग अन्य सेवाओं द्वारा किया जाएगा, जो सभी निर्देशिका संरचना में विभिन्न स्थानों पर स्थित हैं, फिर "../" नहीं होगा हर जगह से काम – user1438940

26

प्रयास करें निर्देशिका जहां नोड प्रक्रिया चल रहा है करने के लिए एक पूर्ण फाइल सिस्टम पथ पाने के लिए आपको process.cwd() उपयोग कर सकते हैं। तो मानते हुए कि आपके एक प्रक्रिया है जो लागू करता /services/template-reading-service.js एक मॉड्यूल के रूप के रूप में /server.js चल रहे हैं, तो आप /सेवा/टेम्पलेट पढ़ने-सेवा से निम्न कर सकते हैं .js:

var appRoot = process.cwd(), 
    templateContent = fs.readFileSync(appRoot + '/templates/my-template.html', 'utf8'); 

है कि तब काम नहीं करता है आप /service/template-reading-service.js एक अलग प्रक्रिया के रूप में, जिस स्थिति में आप जो कुछ भी शुरूआत की आवश्यकता होगी चल रहा जा सकता है प्रक्रिया उस मार्ग को पास करें जिसे आप प्राथमिक एप्लिकेशन के रूप में देखना चाहते हैं जड़। उदाहरण के लिए, यदि /server.js /service/template-reading-service.js को एक अलग प्रक्रिया के रूप में लॉन्च करता है तो /server.js इसे अपनी प्रक्रिया.cwd() पास कर देना चाहिए।

+0

तो, मैंने सोचा कि यह मेरे लिए काम कर सकता है, लेकिन यह ' मेरे सभी वातावरण में काम नहीं करता हूं। मेरे उत्पादन माहौल में, मैं 'हमेशा के लिए' का उपयोग कर रहा हूं, इसलिए 'process.cwd' रिटर्न '/'। – user1438940

+0

भविष्य में लोग इन उत्तरों को देख रहे हैं: process.cwd * जरूरी * वह उत्तर नहीं है जिसे आप ढूंढ रहे हैं। विंडोज़ पर, उदाहरण के लिए, यदि आप किसी .bat फ़ाइल से नोड प्रक्रिया चलाते हैं, तो process.cwd() आपके नोड प्रोजेक्ट की रूट पर नहीं .bat फ़ाइल का पथ देता है। मेरा मानना ​​है कि समान नियम लिनक्स और मैक पर लागू होते हैं। – TKoL

12

स्वीकृत उत्तर गलत है। हार्डकोडिंग path.join(__dirname, '../templates') वही करेगा जो वांछित नहीं है, service-XXX.js फ़ाइल को मुख्य ऐप तोड़ने पर यह मुख्य स्थान को तोड़ देता है (जैसा कि दिया गया उदाहरण services/template)।

process.cwd() का उपयोग कर चलने की प्रक्रिया शुरू करने वाली फ़ाइल के रूट रूट को वापस कर देगा (उदाहरण के लिए, उदाहरण के रूप में /Myuser/myproject/server.js/Myuser/myproject/ देता है)।

यह प्रश्न Determine project root from a running node.js application का डुप्लिकेट है।

उस प्रश्न पर, __dirname उत्तर के लिए उपयुक्त यह उचित है। ग्रीन मार्क, पासर्स द्वारा सावधान रहें।

+2

ऐप-रूट-पथ पैकेज का उपयोग करके मुझे एक भयानक समय था। मेरे ऐप को शुरू करने के दो तरीके थे, नोड lib/my_app.js या bin/my_app.js। 'path.join (__ dirname) 'मैंने प्लेटफॉर्म पर काम करने के लिए बहुत समय और कोड पैचिंग ऐप-रूट-पथ बिताया, अंत में मैंने' path.join (__ dirname) 'पर स्विच किया, जो तब तक काम करेगा जब तक कि परियोजना फाइलें नहीं चारों ओर स्थानांतरित करें। – Ninjaxor

+1

किसी भी भविष्य के लिए इन उत्तरों को देखने वाले लोगों के लिए: process.cwd * जरूरी * वह उत्तर नहीं है जिसे आप ढूंढ रहे हैं। विंडोज़ पर, उदाहरण के लिए, यदि आप किसी .bat फ़ाइल से नोड प्रक्रिया चलाते हैं, तो process.cwd() आपके नोड प्रोजेक्ट की रूट पर नहीं .bat फ़ाइल का पथ देता है। मेरा मानना ​​है कि समान नियम लिनक्स और मैक पर लागू होते हैं। – TKoL