Déterminer la racine du projet à partir d'une application node.js en cours d'exécution


315

Existe-t-il un meilleur moyen que process.cwd()de déterminer le répertoire racine d'un processus node.js en cours d'exécution? Quelque chose comme l'équivalent de Rails.root, mais pour Node.js. Je cherche quelque chose qui soit aussi prévisible et fiable que possible.


1
Y a-t-il une chance que vous puissiez refuser la réponse acceptée, erronée?
Dave Newton

9
essayez process.env.PWD... voir ma réponse ci-dessous.
Alexander Mills

Réponses:


624

Il existe plusieurs façons d'aborder cela, chacune avec ses avantages et ses inconvénients:

require.main.filename

Depuis http://nodejs.org/api/modules.html :

Lorsqu'un fichier est exécuté directement à partir de Node, require.mainest défini sur son module. Cela signifie que vous pouvez déterminer si un fichier a été exécuté directement en testantrequire.main === module

Parce qu'il modulefournit une filenamepropriété (normalement équivalente à __filename), le point d'entrée de l'application en cours peut être obtenu en vérifiant require.main.filename.

Donc, si vous voulez le répertoire de base de votre application, vous pouvez faire:

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

Avantages et inconvénients

Cela fonctionne beaucoup la plupart du temps, mais si vous utilisez votre application avec un lanceur comme PM2 ou en cours d' exécution mocha des tests, cette méthode échouera.

global.X

Le nœud a un objet d'espace de noms global appelé global- tout ce que vous attachez à cet objet sera disponible partout dans votre application. Ainsi, dans votre index.js(ou app.jsquel que soit le nom de votre fichier d'application principal), vous pouvez simplement définir une variable globale:

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

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

Avantages et inconvénients

Fonctionne de manière cohérente mais vous devez vous fier à une variable globale, ce qui signifie que vous ne pouvez pas facilement réutiliser des composants / etc.

process.cwd ()

Cela renvoie le répertoire de travail actuel. Pas fiable du tout, car il est entièrement dépendant de ce répertoire a été lancé le processus de :

$ 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

chemin-racine-app

Pour résoudre ce problème, j'ai créé un module de nœud appelé app-root-path . L'utilisation est simple:

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

Le module app-root-path utilise plusieurs techniques différentes pour déterminer le chemin racine de l'application, en tenant compte des modules installés globalement (par exemple, si votre application s'exécute /var/www/mais que le module est installé dans ~/.nvm/v0.x.x/lib/node/). Cela ne fonctionnera pas à 100% du temps, mais cela fonctionnera dans la plupart des scénarios courants.

Avantages et inconvénients

Fonctionne sans configuration dans la plupart des circonstances. Fournit également de belles méthodes de confort supplémentaires (voir la page du projet). Le plus gros inconvénient est que cela ne fonctionnera pas si:

  • Vous utilisez un lanceur, comme pm2
  • ET , le module n'est pas installé dans le node_modulesrépertoire de votre application (par exemple, si vous l'avez installé globalement)

Vous pouvez contourner cela en définissant une APP_ROOT_PATHvariable d'environnement ou en appelant .setPath()le module, mais dans ce cas, vous feriez probablement mieux d'utiliser la globalméthode.

Variable d'environnement NODE_PATH

Si vous cherchez un moyen de déterminer le chemin racine de l'application actuelle, l'une des solutions ci-dessus est susceptible de fonctionner le mieux pour vous. Si, d'un autre côté, vous essayez de résoudre le problème du chargement fiable des modules d'application, je vous recommande fortement d'examiner la NODE_PATHvariable d'environnement.

Le système de modules de Node recherche des modules dans divers emplacements. L'un de ces emplacements est partout où il process.env.NODE_PATHpointe . Si vous définissez cette variable d'environnement, vous pouvez alors requireutiliser des modules avec le chargeur de module standard sans aucune autre modification.

Par exemple, si vous définissez NODE_PATHsur /var/www/lib, ce qui suit fonctionnerait très bien:

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

Une excellente façon de procéder consiste à utiliser npm:

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

Vous pouvez maintenant démarrer votre application avec npm startet vous êtes en or. Je combine cela avec mon module enforce-node-path , ce qui empêche de charger accidentellement l'application sans NODE_PATHdéfinir. Pour encore plus de contrôle sur l'application des variables d'environnement, voir checkenv .

One gotcha: NODE_PATH doit être défini en dehors de l'application de nœud. Vous ne pouvez pas faire quelque chose comme process.env.NODE_PATH = path.resolve(__dirname)parce que le chargeur de module met en cache la liste des répertoires qu'il recherchera avant l'exécution de votre application.

[ajouté le 4/6/16] Un autre module vraiment prometteur qui tente de résoudre ce problème est ondulé .


1
@Kevin dans ce cas, mocha est le point d'entrée de votre application. Ceci est juste un exemple de la raison pour laquelle il est si difficile de trouver la «racine du projet» - cela dépend tellement de la situation et de ce que vous entendez par «racine du projet».
inxilpro

1
@Kevin, je comprends parfaitement. Mon point est juste que le concept de «racine de projet» est beaucoup plus facile à comprendre pour un humain qu'un ordinateur . Si vous voulez une méthode infaillible, vous devez la configurer. L'utilisation require.main.filenamefonctionnera la plupart du temps, mais pas tout le temps.
inxilpro

2
Tangentiellement lié: c'est une façon incroyablement intelligente d'organiser votre projet Node afin que vous n'ayez pas à vous soucier autant de ce problème: allanhortle.com/2015/02/04/…
inxilpro

1
Je ne sais pas s'il y a eu un changement dans pm2 ou un changement avec Node.js mais require.main.filenamesemble fonctionner avec pm2. Je ne sais pas pour le moka.
Justin Warkentin

8
path.parse(process.mainModule.filename).dir
Cory Robinson

53

__dirnamen'est pas un global; il est local par rapport au module actuel, chaque fichier a donc sa propre valeur locale différente.

Si vous voulez le répertoire racine du processus en cours, vous voulez probablement l’utiliser process.cwd().

Si vous voulez de la prévisibilité et de la fiabilité, vous devrez probablement en faire une exigence de votre application qu'une certaine variable d'environnement soit définie. Votre application recherche MY_APP_HOME(ou peu importe) et si elle est là, et que l'application existe dans ce répertoire, alors tout va bien. S'il n'est pas défini ou si le répertoire ne contient pas votre application, il devrait se terminer avec une erreur invitant l'utilisateur à créer la variable. Il peut être défini dans le cadre d'un processus d'installation.

Vous pouvez lire les variables d'environnement dans le nœud avec quelque chose comme process.env.MY_ENV_VARIABLE.


2
Si utilisé avec prudence, cela pourrait très bien fonctionner. Mais cela donnerait des résultats différents lorsque vous faites bin/server.jsvs cd bin && server.js. (en supposant que ces fichiers js sont marqués comme étant exécutables)
Myrne Stol

1
L'utilisation process.cwd()a fonctionné comme un charme pour moi, même lors de l'exécution de tests de moka. Je vous remercie!
Diogo Eichert du

49

1- créer un fichier à la racine du projet appelez-le settings.js

2- à l'intérieur de ce fichier ajoutez ce code

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

3- à l'intérieur de node_modules créez un nouveau module nommez-le "settings" et à l'intérieur du module index.js écrivez ce code:

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

4- et chaque fois que vous voulez que votre répertoire de projet soit utilisé

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

de cette façon, vous aurez tous les répertoires du projet relatifs à ce fichier;)


33
-1: Pour charger le fichier de paramètres, vous avez besoin d'un chemin, puis obtenir le chemin de référence vers ce fichier? Ne rien résoudre ...
goliatone

2
Voté pour avoir pris le temps de réviser et d'éditer. Cela semble encore fragile, mais c'est peut-être parce qu'il n'y a pas de meilleure façon d'y parvenir
goliatone

8
Une chose que les utilisateurs voudront garder à l'esprit avec cette approche node_modulesest souvent exclue du contrôle de version. Donc, si vous travaillez avec une équipe ou si vous devez cloner votre référentiel, vous devrez trouver une autre solution pour synchroniser ce fichier de paramètres.
Travesty3

@ Travesty3, le module des paramètres est en fait un module vide qui exporte le contenu d'un fichier dans la racine du projet: P
Fareed Alnamrouti

@goliatone Avec sa solution, vous pouvez obtenir le fichier de n'importe où sans connaître son chemin, tout ce que vous devez savoir est "paramètres". Sans cela, vous devez savoir explicitement le nombre de dossiers à sauvegarder jusqu'à ce que vous atteigniez le répertoire du projet. Cela fonctionne car node recherche automatiquement node_modules et sait toujours où cela se trouve.

26

la façon la plus simple d'obtenir la racine globale (en supposant que vous utilisez NPM pour exécuter votre application node.js 'npm start', etc. )

var appRoot = process.env.PWD;

Si vous souhaitez recouper ce qui précède

Supposons que vous souhaitiez recouper process.env.PWDles paramètres de votre application node.js. si vous voulez que certains tests d'exécution vérifient la validité de process.env.PWD, vous pouvez le recouper avec ce code (que j'ai écrit qui semble bien fonctionner). Vous pouvez recouper le nom du dernier dossier dans appRoot avec le npm_package_name dans votre fichier package.json, par exemple:

    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.');
    }

vous pouvez également utiliser ce module NPM: require('app-root-path')qui fonctionne très bien à cet effet


5
Cela fonctionne très bien sur (la plupart) des systèmes Unix. Dès que vous souhaitez que votre module / application npm fonctionne sous Windows, il PWDn'est pas défini et cela échoue.
Jeremy Wiebe

1
process.cwd()
Muhammad Umer

@MuhammadUmer pourquoi serait process.cwd()toujours le même que la racine du projet?
Alexander Mills

si vous l'appelez dans le fichier racine, ce serait
Muhammad Umer

14

J'ai trouvé que cela fonctionne de manière cohérente pour moi, même lorsque l'application est invoquée à partir d'un sous-dossier, comme cela peut être avec certains cadres de test, comme Mocha:

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

Pourquoi ça marche:

Au moment de l'exécution, le nœud crée un registre des chemins d'accès complets de tous les fichiers chargés. Les modules sont chargés en premier, et donc en haut de ce registre. En sélectionnant le premier élément du registre et en renvoyant le chemin avant le répertoire 'node_modules', nous pouvons déterminer la racine de l'application.

Ce n'est qu'une ligne de code, mais pour des raisons de simplicité (mon amour), je l'ai mis en boîte noire dans un module NPM:

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

Prendre plaisir!


1
process.mainModule obsolète depuis: v14.0.0 - utilisez à la require.main.paths[0].split('node_modules')[0].slice(0, -1);place.
RobC

10

Tous ces "répertoires racine" doivent principalement résoudre un chemin virtuel vers un vrai chemin de pile, alors peut-être devriez-vous regarder path.resolve?

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

9

Aussi simple que d'ajouter cette ligne à votre module à la racine, c'est généralement app.js

global.__basedir = __dirname;

_Basedir sera alors accessible à tous vos modules.


8

Vous pouvez peut-être essayer de parcourir vers le haut __filenamejusqu'à ce que vous en trouviez un package.json, et décider que c'est le répertoire principal auquel appartient votre fichier actuel.


7

En fait, je trouve la solution peut-être triviale aussi pour la plus robuste: vous placez simplement le fichier suivant dans le répertoire racine de votre projet: root-path.js qui a le code suivant:

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

4

Une technique que j'ai trouvée utile lors de l'utilisation d'Express consiste à ajouter ce qui suit à app.js avant de définir vos autres routes

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

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

Pas besoin d'utiliser des globaux et vous avez le chemin du répertoire racine comme propriété de l'objet de requête.

Cela fonctionne si votre app.js est à la racine de votre projet, ce qui est le cas par défaut.


4

Ajoutez ceci quelque part vers le début de votre fichier d'application principal (par exemple app.js):

global.__basedir = __dirname;

Cela définit une variable globale qui sera toujours équivalente au répertoire de base de votre application. Utilisez-le comme n'importe quelle autre variable:

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

Facile...


3

Je sais que celui-ci est déjà trop tard. Mais nous pouvons récupérer l'URL racine par deux méthodes

1ère méthode

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

2ème méthode

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

Lien de référence: - https://gist.github.com/geekiam/e2e3e0325abd9023d3a3


3

Il y a une INIT_CWDpropriété sur process.env. C'est ce avec quoi je travaille actuellement dans mon projet.

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

Bonne chance...


1
Fonctionne comme un charme pour un package qui manipule le projet à partir duquel il est appelé en tant qu'étape de post-installation. Je ne l'ai cependant pas encore testé dans une autre couche de dépendance, où un projet utilise une dépendance qui utilise mon package.
JamesDev

1
@JamesDev, INIT_CWDrésout le problème à directorypartir duquel a npm-scriptété exécuté.
Akash

2

si vous voulez déterminer la racine du projet à partir d'une application node.js en cours d'exécution, vous pouvez simplement le faire aussi.

process.mainModule.path

1

En haut du fichier principal, ajoutez:

mainDir = __dirname;

Ensuite, utilisez-le dans n'importe quel fichier dont vous avez besoin:

console.log('mainDir ' + mainDir);
  • mainDirest défini globalement, si vous en avez besoin uniquement dans le fichier actuel - utilisez __dirnameplutôt.
  • fichier principal est généralement dans le dossier racine du projet et est nommé comme main.js, index.js, gulpfile.js.

1

J'utilise ça.

Pour mon module nommé mymodule

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


1

Rendez-le sexy 💃🏻.

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


Trois étapes simples pour résoudre le problème du chemin moche.

  1. Installez le package: npm install sexy-require --save
  2. Inclure require('sexy-require')une fois en haut de votre fichier d'application principal.

    require('sexy-require');
    const routers = require('/routers');
    const api = require('$api');
    ...
  3. Étape facultative. La configuration du chemin peut être définie dans un .pathsfichier sur le répertoire racine de votre projet.

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

Semble décent, dommage qu'il ait un nom aussi ridicule.
JHH

@JHH bien ... J'ai dû trouver un meilleur nom
sultan

1

Cela réduira l'arborescence des répertoires jusqu'à ce qu'elle contienne un node_modulesrépertoire, qui indique généralement la racine de votre projet:

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

Il s'assure également qu'il n'y en a pas node_modulesdans le chemin renvoyé, car cela signifie qu'il est contenu dans une installation de package imbriquée.


1

process.mainModuleest obsolète depuis la version 14.0.0. En se référant à la réponse, veuillez utiliser require.main , le reste tient toujours.

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

Obtenez tous les chemins dans les modules principaux et filtrez ceux avec "node_modules", puis obtenez le premier de la liste des chemins restants. Un comportement inattendu ne générera pas d'erreur, juste un undefined.

Fonctionne bien pour moi, même en appelant ie $ mocha.


0

Créez une fonction dans 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

Vous pouvez simplement ajouter le chemin du répertoire racine dans la variable de l'application express et obtenir ce chemin depuis l'application. Pour cela, ajoutez app.set('rootDirectory', __dirname);votre fichier index.js ou app.js. Et utilisez req.app.get('rootDirectory')pour obtenir le chemin du répertoire racine dans votre code.


0

Vieille question, je sais, mais aucune question de mention à utiliser progress.argv . Le tableau argv inclut un chemin d'accès complet et un nom de fichier (avec ou sans extension .js) qui a été utilisé comme paramètre à exécuter par le nœud. Parce que cela peut également contenir des indicateurs, vous devez filtrer cela.

Ce n'est pas un exemple que vous pouvez utiliser directement (en raison de l'utilisation de mon propre framework) mais je pense que cela vous donne une idée de la façon de le faire. J'utilise également une méthode de cache pour éviter que l'appel de cette fonction sollicite trop le système, surtout lorsqu'aucune extension n'est spécifiée (et qu'une vérification de fichier existe est requise), par exemple:

node myfile

ou

node myfile.js

C'est la raison pour laquelle je le cache, voir aussi le code ci-dessous.


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

Trouver le chemin racine d'une application d'électrons pourrait devenir difficile. Parce que le chemin racine est différent pour le processus principal et le rendu dans différentes conditions telles que la production, le développement et les conditions de package.

J'ai écrit un paquet npm electron-root-path pour capturer le chemin racine d'une application électronique.

$ 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

Cela fera:

path.join(...process.argv[1].split(/\/|\\/).slice(0, -1))


0

Préambule

C'est une très vieille question mais elle semble toujours frapper les nerfs en 2020 comme en 2012. J'ai vérifié toutes les autres réponses et je n'ai pas trouvé de technique (notez que cela a ses limites, mais toutes les autres ne le sont pas applicable dans toutes les situations également).

Processus enfant GIT +

Si vous utilisez GIT comme système de contrôle de version, le problème de la détermination de la racine du projet peut être réduit à (ce que je considérerais comme la racine appropriée du projet - après tout, vous voudriez que votre VCS ait la portée de visibilité la plus complète possible) :

récupérer le chemin racine du référentiel

Puisque vous devez exécuter une commande CLI pour ce faire, nous devrons générer un processus enfant. De plus, comme la racine du projet est très peu susceptible de changer en cours d'exécution, nous pouvons utiliser la version synchrone des child_processAPI du module au démarrage.

J'ai trouvé que spawnSync()c'était le plus approprié pour le poste. Quant à la commande à exécuter, git worktree(avec une --porcelainoption pour faciliter l'analyse) est tout ce dont nous avons besoin pour retrouver le chemin racine absolu.

Dans l'exemple, j'ai choisi de renvoyer un tableau de chemins car il peut y avoir plus d'un arbre de travail (bien qu'ils soient susceptibles d'avoir des chemins communs) juste pour être sûr. Notez que lorsque nous utilisons une commande CLI, l' shelloption doit être définie surtrue (la sécurité ne devrait pas être un problème car il n'y a pas d'entrée non approuvée).

Comparaison d'approche et repli

Comprenant qu'une situation où VCS peut être inaccessible, j'ai inclus quelques solutions de rechange après avoir analysé les documents et autres réponses. Pour résumer, les solutions proposées se résument à (hors modules tiers et spécifiques au package):

| Solution | Avantage | Problème principal |
| ------------------------ | ----------------------- | -------------------------------- |
| `__filename` | pointe vers le fichier module | par rapport au module |
| `__dirname` | pointe vers le module dir | identique à «__filename» |
| promenade dans l'arbre `node_modules` | racine presque garantie | arbre complexe marchant s'il est imbriqué |
| `path.resolve (". ")` | root si CWD est root | identique à `process.cwd ()` |
| `process.argv [1]` | identique à «__filename» | identique à «__filename» |
| `process.env.INIT_CWD` | pointe vers le répertoire `npm run` | nécessite le lancement de `npm` && CLI |
| `process.env.PWD` | pointe vers dir actuel | par rapport au (est le) répertoire de lancement |
| `process.cwd ()` | identique à `env.PWD` | `process.chdir (chemin)` à l'exécution |
| `require.main.filename` | root si `=== module` | échoue sur les modules `require`d |

D'après le tableau de comparaison ci-dessus, les plus universelles sont deux approches:

  • require.main.filenamecomme un moyen facile d'obtenir racine si require.main === moduleest rencontré
  • node_modulesla promenade dans les arbres proposée récemment utilise une autre hypothèse:

si le répertoire du module contient node_modulesdir à l'intérieur, il est probable que ce soit la racine

Pour l'application principale, il obtiendra la racine de l'application et pour le module - sa racine de projet.

Fallback 1. Promenade dans les arbres

Mon implémentation utilise une approche plus laxiste en s'arrêtant une fois qu'un répertoire cible est trouvé car pour un module donné sa racine est sa racine de projet. On peut chaîner les appels ou l'étendre pour rendre la profondeur de recherche configurable:

/**
 * @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));
    };

Fallback 2. Module principal

La deuxième implémentation est triviale

/**
 * @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] :
            [];
    };

la mise en oeuvre

Je suggérerais d'utiliser le marcheur d'arbre comme solution de rechange car il est plus polyvalent:

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);
};

Désavantages

Le plus évident est d'avoir GIT installé et initialisé, ce qui pourrait être indésirable / peu plausible (note latérale: avoir GIT installé sur des serveurs de production n'est pas rare, ni dangereux , cependant). Peut être médiée par des replis comme décrit ci-dessus.

Remarques

  1. Quelques idées pour une extension supplémentaire de l'approche 1:
    • introduire config comme paramètre de fonction
    • export la fonction pour en faire un module
    • vérifier si GIT est installé et / ou initialisé

Références

  1. git worktree référence
  2. spawnSync référence
  3. require.main référence
  4. path.dirname() référence


-1

Essayer path._makeLong('some_filename_on_root.js');

exemple:

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

Cela retournera le chemin complet depuis la racine de votre application de noeud (même position de package.json)


-1

Utilisez simplement:

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

cela fonctionne très bien! path.resolve (".") fonctionne aussi
Noel Schenk

Cela ne donne que le répertoire courant, qui peut ne pas être le répertoire racine.
orad

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.