एक रनिंग नोड.जेएस एप्लिकेशन से प्रोजेक्ट रूट निर्धारित करें


315

क्या process.cwd()रनिंग नोड की मूल निर्देशिका को निर्धारित करने से बेहतर तरीका है। जेएस प्रक्रिया? समतुल्य जैसा कुछ Rails.root, लेकिन Node.js. के लिए मैं एक ऐसी चीज की तलाश कर रहा हूं जो जितना संभव हो उतना पूर्वानुमान और विश्वसनीय हो।


1
कोई भी मौका जिसे आप स्वीकार कर सकते हैं, गलत, उत्तर को स्वीकार कर सकते हैं?
डेव न्यूटन

9
कोशिश process.env.PWD... नीचे मेरा जवाब देखें।
अलेक्जेंडर मिल्स

जवाबों:


624

इसके दृष्टिकोण के कई तरीके हैं, प्रत्येक अपने स्वयं के पेशेवरों और विपक्षों के साथ:

require.main.filename

से http://nodejs.org/api/modules.html :

जब एक फाइल को सीधे नोड से चलाया जाता है, तो require.mainउसे सेट किया जाता है module। इसका मतलब है कि आप यह निर्धारित कर सकते हैं कि एक फ़ाइल को सीधे परीक्षण द्वारा चलाया गया है या नहींrequire.main === module

क्योंकि moduleएक filenameसंपत्ति प्रदान करता है (सामान्य रूप से समतुल्य __filename), वर्तमान एप्लिकेशन के प्रवेश बिंदु को चेक करके प्राप्त किया जा सकता है require.main.filename

इसलिए यदि आप अपने ऐप के लिए आधार निर्देशिका चाहते हैं, तो आप कर सकते हैं:

var path = require('path');
var appDir = path.dirname(require.main.filename);

फायदे नुकसान

यह ज्यादातर समय काम करेगा, लेकिन यदि आप अपना ऐप pm2 जैसे लॉन्चर के साथ चला रहे हैं या मोचा टेस्ट चला रहे हैं , तो यह तरीका विफल हो जाएगा।

global.X

नोड का एक वैश्विक नामस्थान ऑब्जेक्ट है global- जिसे कुछ भी आप इस ऑब्जेक्ट से जोड़ते हैं वह आपके ऐप में हर जगह उपलब्ध होगा। तो, आपके index.js(या app.jsआपकी मुख्य ऐप फ़ाइल का नाम), आप बस एक वैश्विक चर को परिभाषित कर सकते हैं:

// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);

// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');

फायदे नुकसान

लगातार काम करता है लेकिन आपको एक वैश्विक चर पर निर्भर रहना पड़ता है, जिसका अर्थ है कि आप आसानी से घटकों / आदि का पुन: उपयोग नहीं कर सकते हैं।

process.cwd ()

यह वर्तमान कार्यशील निर्देशिका को लौटाता है। विश्वसनीय नहीं है, क्योंकि यह पूरी तरह से इस बात पर निर्भर करता है कि प्रक्रिया किस निर्देशिका से शुरू की गई थी :

$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir

एप्लिकेशन-रूट पथ

इस समस्या को हल करने के लिए, मैंने ऐप-रूट-पथ नामक एक नोड मॉड्यूल बनाया है । उपयोग सरल है:

var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');

एप्लिकेशन-रूट पथ मॉड्यूल कई विभिन्न तकनीकों का उपयोग करता है अनुप्रयोग के रूट पथ निर्धारित करने के लिए, खाते में विश्व स्तर पर स्थापित मॉड्यूल (उदाहरण के लिए, यदि आपके ऐप में चल रहा है ले रही है /var/www/लेकिन मॉड्यूल में स्थापित किया गया है ~/.nvm/v0.x.x/lib/node/)। यह समय के 100% काम नहीं करेगा, लेकिन यह सबसे आम परिदृश्यों में काम करने वाला है।

फायदे नुकसान

अधिकांश परिस्थितियों में विन्यास के बिना काम करता है। कुछ अच्छी अतिरिक्त सुविधा विधियाँ भी प्रदान करता है (परियोजना पृष्ठ देखें)। सबसे बड़ा चोर है कि अगर यह काम नहीं करेगा:

  • आप एक लांचर का उपयोग कर रहे हैं, जैसे pm2
  • और , मॉड्यूल आपके ऐप की node_modulesनिर्देशिका के अंदर स्थापित नहीं है (उदाहरण के लिए, यदि आपने इसे विश्व स्तर पर स्थापित किया है)

आप इसके चारों ओर एक APP_ROOT_PATHपर्यावरण चर स्थापित करके , या .setPath()मॉड्यूल पर कॉल करके प्राप्त कर सकते हैं , लेकिन उस स्थिति में, आप शायद globalविधि का उपयोग कर रहे हैं ।

NODE_PATH पर्यावरण चर

यदि आप वर्तमान एप्लिकेशन के रूट पथ को निर्धारित करने के लिए रास्ता ढूंढ रहे हैं , तो उपरोक्त समाधानों में से एक आपके लिए सबसे अच्छा काम करने की संभावना है। यदि, दूसरी ओर, आप एप्लिकेशन मॉड्यूल को लोड करने की समस्या को मज़बूती से हल करने की कोशिश कर रहे हैं, तो मैं अत्यधिक NODE_PATHपर्यावरण चर में देखने की सलाह देता हूं ।

नोड की मॉड्यूल प्रणाली विभिन्न स्थानों में मॉड्यूल की तलाश करती है। इन स्थानों में से एक जहाँ भी process.env.NODE_PATHबिंदु हैं । यदि आप इस पर्यावरण चर को सेट करते हैं, तो आप requireबिना किसी अन्य परिवर्तन के मानक मॉड्यूल लोडर के साथ मॉड्यूल कर सकते हैं।

उदाहरण के लिए, यदि आप सेट NODE_PATHकरते हैं /var/www/lib, तो निम्नलिखित ठीक काम करेगा:

require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js

इसका उपयोग करने का एक शानदार तरीका है npm:

"scripts": {
    "start": "NODE_PATH=. node app.js"
}

अब आप अपना ऐप शुरू कर सकते हैं npm startऔर आप सुनहरे हो सकते हैं। मैं इसे अपने एनफोर्समेंट-नोड-पथ मॉड्यूल के साथ जोड़ती हूं , जो बिना NODE_PATHसेट के गलती से ऐप लोड करने से रोकता है । पर्यावरण चर को लागू करने पर और अधिक नियंत्रण के लिए, चेकेनव देखें ।

एक गेटा: नोड ऐप के बाहर सेट किया NODE_PATH जाना चाहिए । आप ऐसा कुछ नहीं कर सकते क्योंकि मॉड्यूल लोडर निर्देशिकाओं की सूची को कैश करता है जो आपके ऐप के चलने से पहले खोज करेगा।process.env.NODE_PATH = path.resolve(__dirname)

[जोड़ा 4/6/16] एक और वास्तव में आशाजनक मॉड्यूल जो इस समस्या को हल करने का प्रयास करता है, लहराती है


1
@ केविन इस मामले में, मोचा आपके आवेदन का प्रवेश बिंदु है। यह सिर्फ एक उदाहरण है कि "प्रोजेक्ट रूट" को ढूंढना इतना मुश्किल क्यों है - यह स्थिति पर बहुत निर्भर करता है और "रूट रूट" से आपका क्या मतलब है।
inxilpro

1
@ केविन मैं पूरी तरह से समझता हूं। मेरा कहना सिर्फ इतना है कि "प्रोजेक्ट रूट" की अवधारणा मनुष्य के लिए कंप्यूटर की तुलना में समझना बहुत आसान है । यदि आप एक मूर्ख-प्रूफ विधि चाहते हैं, तो आपको इसे कॉन्फ़िगर करने की आवश्यकता है। का उपयोग कर समय के सबसे काम करेंगे , लेकिन समय के सभी नहीं । require.main.filename
inxilpro

2
तात्कालिक रूप से संबंधित: यह आपके नोड प्रोजेक्ट को व्यवस्थित करने के लिए एक अविश्वसनीय रूप से चतुर तरीका है ताकि आपको इस समस्या के बारे में इतना परेशान न होना पड़े: allanhortle.com/2015/02/04/…
inxilpro

1
मुझे नहीं पता कि pm2 में कोई बदलाव हुआ था या Node.js के साथ कोई बदलाव हुआ था, लेकिन require.main.filenamepm2 के साथ काम करना प्रतीत होता है। मोचा के बारे में नहीं जानते।
जस्टिन वर्केंटिन

8
path.parse(process.mainModule.filename).dir
कोरी रॉबिन्सन

53

__dirnameवैश्विक नहीं है; यह वर्तमान मॉड्यूल के लिए स्थानीय है इसलिए प्रत्येक फ़ाइल का अपना स्थानीय, अलग मूल्य है।

यदि आप रनिंग प्रक्रिया की रूट डायरेक्टरी चाहते हैं, तो आप संभवतः उपयोग करना चाहते हैं process.cwd()

यदि आप पूर्वानुमान और विश्वसनीयता चाहते हैं, तो आपको संभवतः इसे अपने आवेदन की आवश्यकता बनाने के लिए ज़रूरी है कि एक निश्चित वातावरण चर निर्धारित किया जाए। आपका ऐप ढूंढता है MY_APP_HOME(या जो भी हो) और यदि यह वहां है, और एप्लिकेशन उस निर्देशिका में मौजूद है तो सब ठीक है। यदि यह अपरिभाषित है या निर्देशिका में आपका आवेदन नहीं है, तो यह उपयोगकर्ता को चर बनाने के लिए संकेत देने वाली त्रुटि से बाहर निकलना चाहिए। इसे इंस्टॉल प्रक्रिया के एक भाग के रूप में सेट किया जा सकता है।

आप कुछ के साथ नोड में पर्यावरण चर पढ़ सकते हैं process.env.MY_ENV_VARIABLE


2
अगर सावधानी के साथ प्रयोग किया जाए तो यह बहुत अच्छा काम कर सकता है। लेकिन यह bin/server.jsबनाम करते समय अलग परिणाम देगा cd bin && server.js। (इन js फ़ाइलों को निष्पादन योग्य माना जा रहा है)
Myrne Stol

1
का उपयोग करना process.cwd()मेरे लिए एक आकर्षण की तरह काम किया है, तब भी जब मोचा परीक्षण चल रहा है। धन्यवाद!
दिओगो आइचर्ट

49

1- प्रोजेक्ट रूट में एक फाइल बनाएं जिसे सेटिंग्स कहा जाए। js

2- इस फाइल के अंदर इस कोड को जोड़ें

module.exports = {
    POST_MAX_SIZE : 40 , //MB
    UPLOAD_MAX_FILE_SIZE: 40, //MB
    PROJECT_DIR : __dirname
};

3- अंदर नोड_मॉड्यूल्स एक नया मॉड्यूल नाम बनाते हैं इसे "सेटिंग" और मॉड्यूल इंडेक्स के अंदर। इस कोड को लिखें:

module.exports = require("../../settings");

4- और किसी भी समय आप अपनी परियोजना निर्देशिका का उपयोग करना चाहते हैं

var settings = require("settings");
settings.PROJECT_DIR; 

इस तरह से आपके पास इस फ़ाइल के सापेक्ष सभी परियोजना निर्देशिकाएं होंगी;)


33
-1: सेटिंग्स फ़ाइल को लोड करने के लिए आपको एक पथ की आवश्यकता है, फिर उस फ़ाइल के लिए संदर्भ पथ प्राप्त करें? कुछ भी हल नहीं कर रहा है ...
goliatone

2
समीक्षा करने और संपादित करने के लिए समय निकालने के लिए तैयार किया गया। यह अभी भी भंगुरता महसूस करता है, लेकिन यह सिर्फ इसलिए हो सकता है क्योंकि इसे प्राप्त करने का एक बेहतर तरीका नहीं है
गोलियोनोन

8
कुछ उपयोगकर्ता इस दृष्टिकोण को ध्यान में रखना चाहेंगे जो node_modulesअक्सर संस्करण नियंत्रण से बाहर रखा गया है। इसलिए यदि आप एक टीम के साथ काम करते हैं या आपको अपने भंडार को क्लोन करने की आवश्यकता होती है, तो आपको उस सेटिंग फ़ाइल को सिंक में रखने के लिए एक और समाधान के साथ आना होगा।
ट्रैवेस्टी 3

@ Travesty3 सेटिंग्स मॉड्यूल वास्तव में एक खाली मॉड्यूल है जो प्रोजेक्ट रूट में एक फ़ाइल की सामग्री का निर्यात कर रहा है: P
फरीद अलनामृती

@goliatone उसके समाधान से आप फ़ाइल को उसके पथ को जाने बिना कहीं से भी प्राप्त कर सकते हैं, आपको बस यह जानना होगा कि "सेटिंग" है। इसके बिना, आपको स्पष्ट रूप से यह जानना होगा कि परियोजना निर्देशिका तक पहुंचने तक कितने फ़ोल्डर वापस करने हैं। यह काम करता है क्योंकि नोड स्वचालित रूप से नोड_मॉडल खोजता है और हमेशा जानता है कि वह कहां है।

26

वैश्विक रूट प्राप्त करने का सबसे आसान तरीका ( मान लें कि आप अपना नोड चलाने के लिए एनपीएम का उपयोग करते हैं। जेएस ऐप 'एनपीएम स्टार्ट', आदि )

var appRoot = process.env.PWD;

यदि आप उपरोक्त को क्रॉस-सत्यापित करना चाहते हैं

कहते हैं कि process.env.PWDआप नोड की सेटिंग्स के साथ क्रॉस-चेक करना चाहते हैं । जेएस आवेदन। अगर आप चाहते हैं कि कुछ रनटाइम टेस्ट की वैधता की जांच करें process.env.PWD, तो आप इसे इस कोड के साथ क्रॉस-चेक कर सकते हैं (जो मैंने लिखा था कि यह अच्छी तरह से काम करता है)। आप अपने पैकेज में npm_package_name के साथ appRoot में अंतिम फ़ोल्डर का नाम क्रॉस-चेक कर सकते हैं। उदाहरण के लिए, फ़ाइल:

    var path = require('path');

    var globalRoot = __dirname; //(you may have to do some substring processing if the first script you run is not in the project root, since __dirname refers to the directory that the file is in for which __dirname is called in.)

    //compare the last directory in the globalRoot path to the name of the project in your package.json file
    var folders = globalRoot.split(path.sep);
    var packageName = folders[folders.length-1];
    var pwd = process.env.PWD;
    var npmPackageName = process.env.npm_package_name;
    if(packageName !== npmPackageName){
        throw new Error('Failed check for runtime string equality between globalRoot-bottommost directory and npm_package_name.');
    }
    if(globalRoot !== pwd){
        throw new Error('Failed check for runtime string equality between globalRoot and process.env.PWD.');
    }

आप इस एनपीएम मॉड्यूल का भी उपयोग कर सकते हैं: require('app-root-path')जो इस उद्देश्य के लिए बहुत अच्छा काम करता है


5
यह (अधिकांश) यूनिक्स सिस्टम पर बहुत अच्छा काम करता है। जैसे ही आप चाहते हैं कि आपका npm मॉड्यूल / ऐप विंडोज पर काम करे, PWDअपरिभाषित है और यह विफल हो जाता है।
जेरेमी विएबे


@MuhammadUmer process.cwd()हमेशा प्रोजेक्ट रूट के समान क्यों होगा ?
अलेक्जेंडर मिल्स

अगर आप इसे रूट फाइल में कहते हैं तो यह होगा
मुहम्मद उमर

14

मैंने पाया है कि यह मेरे लिए लगातार काम करता है, तब भी जब एप्लिकेशन को एक सब-फ़ोल्डर से मंगाया जाता है, क्योंकि यह कुछ टेस्ट फ्रेमवर्क के साथ हो सकता है, जैसे मोचा:

process.mainModule.paths[0].split('node_modules')[0].slice(0, -1);

यह क्यों काम करता है:

रनटाइम नोड पर सभी भरी हुई फ़ाइलों के पूर्ण पथ की एक रजिस्ट्री बनाता है। मॉड्यूल पहले लोड किए जाते हैं, और इस प्रकार इस रजिस्ट्री के शीर्ष पर। रजिस्ट्री के पहले तत्व का चयन करके और 'node_modules' निर्देशिका से पहले पथ को वापस करके हम एप्लिकेशन के रूट को निर्धारित करने में सक्षम हैं।

यह कोड की सिर्फ एक पंक्ति है, लेकिन सादगी के लिए (मेरी खातिर), मैंने इसे एनपीएम मॉड्यूल में काला कर दिया:

https://www.npmjs.com/package/node-root.pddivine

का आनंद लें!


1
process.mainModule इसके बाद से वंचित: v14.0.0 - require.main.paths[0].split('node_modules')[0].slice(0, -1);इसके बजाय उपयोग करें ।
रॉब

10

इन सभी "रूट डायर" को ज्यादातर कुछ आभासी पथ को एक वास्तविक ढेर पथ पर हल करने की आवश्यकता होती है, तो क्या आपको देखना चाहिए path.resolve?

var path= require('path');
var filePath = path.resolve('our/virtual/path.ext');

9

सरल रूप में इस लाइन को रूट में अपने मॉड्यूल में जोड़ें, आमतौर पर यह app.js है

global.__basedir = __dirname;

तब _badeir आपके सभी मॉड्यूल के लिए सुलभ होगा।


8

हो सकता है कि आप __filenameतब तक ऊपर की ओर ट्रेसिंग का प्रयास कर सकते हैं जब तक कि आपको कोई पता न चल जाए package.json, और यह तय करें कि आपकी वर्तमान फ़ाइल मुख्य निर्देशिका से संबंधित है।


7

वास्तव में, मैं शायद तुच्छ समाधान भी सबसे अधिक मजबूत पाता हूं: आप बस अपनी परियोजना के रूट डायरेक्टरी में निम्नलिखित फाइल रखें: रूट-पाथ.जेएस जिसमें निम्नलिखित कोड हो:

import * as path from 'path'
const projectRootPath = path.resolve(__dirname)
export const rootPath = projectRootPath

4

एक तकनीक जिसे मैंने एक्सप्रेस का उपयोग करते समय उपयोगी पाया है, अपने अन्य मार्गों को सेट करने से पहले app.js में निम्न जोड़ना है

// set rootPath
app.use(function(req, res, next) {
  req.rootPath = __dirname;
  next();
});

app.use('/myroute', myRoute);

ग्लोबल्स का उपयोग करने की आवश्यकता नहीं है और आपके पास अनुरोध ऑब्जेक्ट की संपत्ति के रूप में रूट निर्देशिका का मार्ग है।

यह काम करता है यदि आपका app.js आपके प्रोजेक्ट के मूल में है, जो डिफ़ॉल्ट रूप से है, यह है।


4

इसे अपनी मुख्य ऐप फ़ाइल (जैसे app.js) की शुरुआत की ओर कहीं जोड़ें:

global.__basedir = __dirname;

यह एक वैश्विक चर सेट करता है जो हमेशा आपके ऐप के आधार डायर के बराबर होगा। इसे किसी अन्य चर की तरह ही उपयोग करें:

const yourModule = require(__basedir + '/path/to/module.js');

सरल...


3

मुझे पता है कि यह पहले से ही बहुत देर हो चुकी है। लेकिन हम दो तरीकों से रूट URL प्राप्त कर सकते हैं

पहली विधि

var path = require('path');
path.dirname(require.main.filename);

दूसरी विधि

var path = require('path');
path.dirname(process.mainModule.filename);

संदर्भ लिंक: - https://gist.github.com/geekiam/e2e3e0325abd9023d3a3


3

INIT_CWDपर एक संपत्ति है process.env। यह वही है जो मैं इस समय अपनी परियोजना में काम कर रहा हूं।

const {INIT_CWD} = process.env; // process.env.INIT_CWD 
const paths = require(`${INIT_CWD}/config/paths`);

शुभ लाभ...


1
एक पैकेज के लिए एक आकर्षण की तरह काम करता है जो उस परियोजना में हेरफेर करता है जिसे इसे पोस्टइंस्टॉल कदम के रूप में कहा जा रहा है। हालांकि, मैंने अभी तक निर्भरता की एक और परत में इसका परीक्षण नहीं किया है, जहां एक परियोजना एक निर्भरता का उपयोग करती है जो मेरे पैकेज का उपयोग करती है।
जेम्सडेव

1
@JamesDev, INIT_CWDउस directoryसे हल होता है जिसमें से बाहर निकाला गया npm-scriptथा।
आकाश

2

यदि आप एक रनिंग नोड से प्रोजेक्ट रूट को निर्धारित करना चाहते हैं। जेएस एप्लिकेशन आप बस भी कर सकते हैं।

process.mainModule.path

1

मुख्य फ़ाइल जोड़ने के शीर्ष पर:

mainDir = __dirname;

फिर इसे अपनी जरूरत की किसी भी फ़ाइल में उपयोग करें:

console.log('mainDir ' + mainDir);
  • mainDirविश्व स्तर पर परिभाषित किया गया है, अगर आपको इसकी आवश्यकता केवल वर्तमान फ़ाइल में है - __dirnameइसके बजाय उपयोग करें ।
  • मुख्य फ़ाइल परियोजना के रूट फ़ोल्डर में आमतौर पर है और इस तरह के नाम पर है main.js, index.js, gulpfile.js

1

मैं इसका उपयोग करता हूं।

मेरे मॉड्यूल नाम के लिए mymodule

var BASE_DIR = __dirname.replace(/^(.*\/mymodule)(.*)$/, '$1')


1

इसे सेक्सी बनाओ 💃🏻

const users = require('../../../database/users'); // 👎 what you have
// OR
const users = require('$db/users'); // 👍 no matter how deep you are
const products = require('/database/products'); // 👍 alias or pathing from root directory


बदसूरत रास्ते के मुद्दे को हल करने के लिए तीन सरल कदम।

  1. पैकेज स्थापित करें: npm install sexy-require --save
  2. require('sexy-require')अपनी मुख्य एप्लिकेशन फ़ाइल के शीर्ष पर एक बार शामिल करें ।

    require('sexy-require');
    const routers = require('/routers');
    const api = require('$api');
    ...
  3. वैकल्पिक कदम। पथ कॉन्फ़िगरेशन .pathsको आपकी परियोजना की रूट निर्देशिका में फ़ाइल में परिभाषित किया जा सकता है ।

    $db = /server/database
    $api-v1 = /server/api/legacy
    $api-v2 = /server/api/v2

सभ्य लगता है, बहुत बुरा यह एक हास्यास्पद नाम था।
जेएचएच

@ जेएचएच अच्छी तरह से ... मुझे एक बेहतर नाम ढूंढना था
सुल्तान

1

यह निर्देशिका ट्री को तब तक नीचे ले जाएगा, जब तक कि इसमें कोई node_modulesनिर्देशिका न हो, जो आमतौर पर आपकी परियोजना को इंगित करता है:

const fs = require('fs')
const path = require('path')

function getProjectRoot(currentDir = __dirname.split(path.sep)) {
  if (!currentDir.length) {
    throw Error('Could not find project root.')
  }
  const nodeModulesPath = currentDir.concat(['node_modules']).join(path.sep)
  if (fs.existsSync(nodeModulesPath) && !currentDir.includes('node_modules')) {
    return currentDir.join(path.sep)
  }
  return this.getProjectRoot(currentDir.slice(0, -1))
}

यह भी सुनिश्चित करता है कि node_modulesलौटे मार्ग में कोई भी नहीं है, क्योंकि इसका मतलब है कि यह एक नेस्टेड पैकेज इंस्टॉल में निहित है।


1

process.mainModuleहै पदावनत v 14.0.0 के बाद से। जवाब का जिक्र करते समय, कृपया उपयोग करें require.main , बाकी अभी भी है।

process.mainModule.paths
  .filter(p => !p.includes('node_modules'))
  .shift()

मुख्य मॉड्यूल में सभी पथ प्राप्त करें और "नोड_मॉड्यूल्स" के साथ उन लोगों को फ़िल्टर करें, फिर शेष पथ सूची में से पहला प्राप्त करें। अप्रत्याशित व्यवहार त्रुटि, बस एक फेंक नहीं होगा undefined

मेरे लिए अच्छी तरह से काम करता है, यहां तक ​​कि जब भी बुला रहा है $ mocha


0

App.js में एक समारोह बनाएँ

/*Function to get the app root folder*/

var appRootFolder = function(dir,level){
    var arr = dir.split('\\');
    arr.splice(arr.length - level,level);
    var rootFolder = arr.join('\\');
    return rootFolder;
}

// view engine setup
app.set('views', path.join(appRootFolder(__dirname,1),'views'));

0

आप बस एक्सप्रेस एप्लिकेशन चर में रूट निर्देशिका पथ जोड़ सकते हैं और इस पथ को ऐप से प्राप्त कर सकते हैं। इसके लिए app.set('rootDirectory', __dirname);अपने index.js या app.js फ़ाइल में जोड़ें । और req.app.get('rootDirectory')अपने कोड में रूट डायरेक्टरी पथ प्राप्त करने के लिए उपयोग करें।


0

पुराना प्रश्न, मुझे पता है, हालांकि उपयोग करने के लिए कोई प्रश्न नहीं है progress.argv। Argv सरणी में एक पूर्ण pathname और फ़ाइल नाम (.js एक्सटेंशन के साथ या बिना) शामिल है, जिसका उपयोग नोड द्वारा निष्पादित किए जाने वाले पैरामीटर के रूप में किया गया था। क्योंकि इसमें झंडे भी हो सकते हैं, आपको इसे अवश्य फ़िल्टर करना चाहिए।

यह एक उदाहरण नहीं है जिसका आप सीधे उपयोग कर सकते हैं (क्योंकि अपने स्वयं के ढांचे का उपयोग करके) लेकिन मुझे लगता है कि यह आपको कुछ विचार देता है कि इसे कैसे करना है। उदाहरण के लिए, इस फ़ंक्शन को कॉल करने से बचने के लिए मैं कैश विधि का भी उपयोग करता हूं, खासकर जब कोई एक्सटेंशन निर्दिष्ट नहीं किया जाता है (और फ़ाइल मौजूद चेक की आवश्यकता होती है), उदाहरण के लिए:

node myfile

या

node myfile.js

यही कारण है कि मैं इसे कैश करता हूं, नीचे कोड भी देखें।


function getRootFilePath()
{
        if( !isDefined( oData.SU_ROOT_FILE_PATH ) )
        {
            var sExt = false;

            each( process.argv, function( i, v )
            {
                 // Skip invalid and provided command line options
                if( !!v && isValidString( v ) && v[0] !== '-' )
                {
                    sExt = getFileExt( v );

                    if( ( sExt === 'js' ) || ( sExt === '' && fileExists( v+'.js' )) )
                    {

                        var a = uniformPath( v ).split("/"); 

                         // Chop off last string, filename
                        a[a.length-1]='';

                         // Cache it so we don't have to do it again.
                        oData.SU_ROOT_FILE_PATH=a.join("/"); 

                         // Found, skip loop
                        return true;
                    }
                }
            }, true ); // <-- true is: each in reverse order
        }

        return oData.SU_ROOT_FILE_PATH || '';
    }
}; 

0

इलेक्ट्रॉन ऐप के रूट का पता लगाना मुश्किल हो सकता है। क्योंकि मुख्य पथ विभिन्न प्रक्रिया जैसे उत्पादन, विकास और पैकेज्ड स्थितियों के तहत मुख्य प्रक्रिया और रेंडरर के लिए अलग-अलग होता है।

मैंने एक इलेक्ट्रॉन ऐप के रूट पथ को पकड़ने के लिए एक npm पैकेज इलेक्ट्रॉन-रूट-पथ लिखा है ।

$ npm install electron-root-path

or 

$ yarn add electron-root-path


// Import ES6 way
import { rootPath } from 'electron-root-path';

// Import ES2015 way
const rootPath = require('electron-root-path').rootPath;

// e.g:
// read a file in the root
const location = path.join(rootPath, 'package.json');
const pkgInfo = fs.readFileSync(location, { encoding: 'utf8' });



0

प्रस्तावना

यह एक बहुत पुराना प्रश्न है, लेकिन यह अभी भी 2012 की तरह 2020 में तंत्रिका पर प्रहार करता है। मैंने अन्य सभी उत्तरों की जाँच की है और एक टेक्टिक नहीं पाया है (ध्यान दें कि इसकी सीमाएँ हैं, लेकिन अन्य सभी नहीं हैं हर स्थिति में लागू है)।

जीआईटी + बाल प्रक्रिया

यदि आप जीआईटी को अपने संस्करण नियंत्रण प्रणाली के रूप में उपयोग कर रहे हैं, तो प्रोजेक्ट रूट को निर्धारित करने की समस्या को कम किया जा सकता है (जो मैं परियोजना की उचित जड़ पर विचार करूंगा - आखिरकार, आप चाहेंगे कि आपका वीसीएस पूरी दृश्यता गुंजाइश संभव हो) :

पुनरावर्ती रिपॉजिटरी रूट पथ

चूँकि आपको ऐसा करने के लिए एक CLI कमांड चलाना होगा, इसलिए हमें एक चाइल्ड प्रोसेस को स्पान करना होगा। इसके अतिरिक्त, चूंकि प्रोजेक्ट रूट मिड-रनटाइम को बदलने की अत्यधिक संभावना नहीं है, इसलिए हम child_processस्टार्टअप पर मॉड्यूल एपीआई के तुल्यकालिक संस्करण का उपयोग कर सकते हैं ।

मुझे spawnSync()नौकरी के लिए सबसे उपयुक्त पाया गया। जैसा कि चलाने के लिए वास्तविक आदेश के लिए, git worktree( --porcelainपार्सिंग में आसानी के लिए एक विकल्प के साथ ) हम सभी को पूर्ण रूट पथ को पुनः प्राप्त करने की आवश्यकता है।

नमूने में मैंने पथों की एक सरणी लौटाने का विकल्प चुना क्योंकि एक से अधिक कार्यपट्टी हो सकती हैं (हालाँकि उनके सामान्य मार्ग होने की संभावना है) बस सुनिश्चित होने के लिए। ध्यान दें कि जैसा कि हम एक CLI कमांड का उपयोग करते हैं, shellविकल्प को सेट किया trueजाना चाहिए (सुरक्षा कोई समस्या नहीं होनी चाहिए क्योंकि कोई अविश्वसनीय इनपुट नहीं है)।

तुलना और कमियां

यह समझते हुए कि ऐसी स्थिति जहां वीसीएस अप्राप्य हो सकता है, मैंने डॉक्स और अन्य उत्तरों का विश्लेषण करने के बाद कुछ कमियां शामिल की हैं। योग करने के लिए, समाधान के नीचे (तीसरे पक्ष के मॉड्यूल और पैकेज-विशिष्ट को छोड़कर) फोड़ा प्रस्तावित है:

| समाधान | फायदा | मुख्य समस्या |
| ------------------------ | ----------------------- | -------------------------------- |
| `__filename` | मॉड्यूल फ़ाइल के लिए अंक | मॉड्यूल के सापेक्ष |
| `__dirname` | मॉड्यूल डीआईआर के अंक | उसी के रूप में `__filename` |
| `नोड_मॉड्यूल्स` ट्री वॉक | लगभग गारंटी रूट | जटिल पेड़ चलना अगर नेस्टेड |
| `path.resolve ("। ")` | अगर CWD रूट है तो रूट | उसी के रूप में `process.cwd ()` |
| `process.argv [1]` | उसी के रूप में `__filename` | उसी के रूप में `__filename` |
| `process.env.INIT_CWD` | अंक `npm run` dir | आवश्यकता `npm` और& CLI लॉन्च |
| `process.env.PWD` | वर्तमान dir के अंक | रिश्तेदार (है) लॉन्च dir |
| `process.cwd ()` | समान रूप से `env.PWD` | `process.chdir (पथ)` रनटाइम पर |
| `आवश्यकता.main.filename` | रूट अगर `=== मॉड्यूल` | विफल रहता है `आवश्यकता` मॉड्यूल पर |

ऊपर की तुलना तालिका से, सबसे सार्वभौमिक दो दृष्टिकोण हैं:

  • require.main.filenameअगर require.main === moduleमिले तो जड़ पाने का आसान तरीका है
  • node_modulesहाल ही में प्रस्तावित ट्री वॉक एक और धारणा का उपयोग करता है:

यदि मॉड्यूल की node_modulesनिर्देशिका के अंदर dir है, तो यह मूल होने की संभावना है

मुख्य ऐप के लिए इसे ऐप रूट मिलेगा और मॉड्यूल के लिए - इसकी प्रोजेक्ट रूट।

पतवार 1. पेड़ की टहनी

एक टारगेट डाइरेक्टरी को एक बार दिए गए मॉड्यूल के लिए पाए जाने के बाद मेरा क्रियान्वयन एक अधिक ढीला दृष्टिकोण का उपयोग करता है, इसकी जड़ इसकी परियोजना जड़ है। कोई कॉल को चेन कर सकता है या खोज गहराई को कॉन्फ़िगर करने के लिए इसे बढ़ा सकता है:

/**
 * @summary gets root by walking up node_modules
 * @param {import("fs")} fs
 * @param {import("path")} pt
 */
const getRootFromNodeModules = (fs, pt) =>

    /**
     * @param {string} [startPath]
     * @returns {string[]}
     */
    (startPath = __dirname) => {

        //avoid loop if reached root path
        if (startPath === pt.parse(startPath).root) {
            return [startPath];
        }

        const isRoot = fs.existsSync(pt.join(startPath, "node_modules"));

        if (isRoot) {
            return [startPath];
        }

        return getRootFromNodeModules(fs, pt)(pt.dirname(startPath));
    };

पतन 2. मुख्य मॉड्यूल

दूसरा कार्यान्वयन तुच्छ है

/**
 * @summary gets app entry point if run directly
 * @param {import("path")} pt
 */
const getAppEntryPoint = (pt) =>

    /**
     * @returns {string[]}
     */
    () => {

        const { main } = require;

        const { filename } = main;

        return main === module ?
            [pt.parse(filename).dir] :
            [];
    };

कार्यान्वयन

मेरा सुझाव है कि ट्री वॉकर को फॉलबैक के रूप में उपयोग करें क्योंकि यह अधिक बहुमुखी है:

const { spawnSync } = require("child_process");
const pt = require('path');
const fs = require("fs");

/**
 * @summary returns worktree root path(s)
 * @param {function : string[] } [fallback]
 * @returns {string[]}
 */
const getProjectRoot = (fallback) => {

    const { error, stdout } = spawnSync(
        `git worktree list --porcelain`,
        {
            encoding: "utf8",
            shell: true
        }
    );

    if (!stdout) {
        console.warn(`Could not use GIT to find root:\n\n${error}`);
        return fallback ? fallback() : [];
    }

    return stdout
        .split("\n")
        .map(line => {
            const [key, value] = line.split(/\s+/) || [];
            return key === "worktree" ? value : "";
        })
        .filter(Boolean);
};

नुकसान

सबसे स्पष्ट जीआईटी स्थापित और आरंभिक है जो अवांछनीय / अनुमानित हो सकता है (साइड नोट: उत्पादन सर्वर पर स्थापित जीआईटी असामान्य नहीं है, और न ही यह असुरक्षित है , हालांकि)। ऊपर बताए अनुसार कमियों द्वारा मध्यस्थता की जा सकती है।

टिप्पणियाँ

  1. दृष्टिकोण 1 के और विस्तार के लिए विचारों की एक जोड़ी:
    • फ़ंक्शन पैरामीटर के रूप में कॉन्‍फ़िगर करें
    • export फ़ंक्शन इसे एक मॉड्यूल बनाने के लिए
    • जांचें कि क्या GIT स्थापित है और / या आरंभिक है

संदर्भ

  1. git worktree संदर्भ
  2. spawnSync संदर्भ
  3. require.main संदर्भ
  4. path.dirname() संदर्भ


-1

प्रयत्न path._makeLong('some_filename_on_root.js');

उदाहरण:

cons path = require('path');
console.log(path._makeLong('some_filename_on_root.js');

वह आपके नोड एप्लिकेशन (मूल पैकेज की एक ही स्थिति) की जड़ से पूरा रास्ता लौटाएगा


-1

महज प्रयोग करें:

 path.resolve("./") ... output is your project root directory

यह बहुत अच्छा काम करता है! path.resolve ("") भी काम करता है
Noel Schenk

यह केवल वर्तमान निर्देशिका देता है, जो रूट निर्देशिका नहीं हो सकता है।
orad

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.