Y a-t-il un autre moyen, autre que process.cwd()
pour obtenir le nom du chemin du répertoire racine du projet en cours. Est-ce que Node implémente quelque chose comme la propriété de Ruby, Rails.root
,. Je cherche quelque chose qui soit constant et fiable.
Réponses
Trop de publicités?Il existe de nombreuses façons d'aborder cette question, chacune ayant ses avantages et ses inconvénients :
require.main.filename
De http://nodejs.org/api/modules.html :
Lorsqu'un fichier est exécuté directement depuis Node,
require.main
est fixé à sonmodule
. Cela signifie que vous pouvez déterminer si un fichier a été exécuté directement en testantrequire.main === module
Porque
module
fournit unfilename
(normalement équivalent à__filename
), le point d'entrée de l'application courante peut être obtenu en vérifiantrequire.main.filename
.
Donc si vous voulez le répertoire de base pour votre application, vous pouvez le faire :
const { dirname } = require('path');
const appDir = dirname(require.main.filename);
Avantages et inconvénients
Cela fonctionnera très bien la plupart du temps, mais si vous exécutez votre application avec un lanceur comme pm2 ou en cours d'exécution moka cette méthode échouera.
module.paths
Le nœud publie tous les chemins de recherche de modules sur le site web de l'entreprise. module.paths
. Nous pouvons les parcourir et choisir le premier qui se résout.
async function getAppPath() {
const { dirname } = require('path');
const { constants, promises: { access } } = require('fs');
for (let path of module.paths) {
try {
await access(path, constants.F_OK);
return dirname(path);
} catch (e) {
// Just move on to next path
}
}
}
Avantages et inconvénients
Cette méthode fonctionne parfois, mais n'est pas fiable lorsqu'elle est utilisée dans un paquet, car elle peut renvoyer le répertoire dans lequel le paquet est installé plutôt que le répertoire dans lequel l'application est installée.
Utilisation d'une variable globale
Node possède un objet d'espace de nom global appelé global
- Tout ce que vous attachez à cet objet sera disponible partout dans votre application. Ainsi, dans votre index.js
(ou app.js
ou quelle que soit votre application principale ), 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 appuyer sur une variable globale, ce qui signifie que vous ne pouvez pas réutiliser facilement les composants/etc.
process.cwd()
Ceci renvoie le répertoire de travail actuel. Pas fiable du tout, car il dépend entièrement du répertoire dans lequel le processus a été lancé. 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
app-Root-path
Pour résoudre ce problème, j'ai créé un module de nœud appelé app-Root-path . L'utilisation est simple :
const appRoot = require('app-root-path');
const myModule = require(`${ appRoot }/lib/my-module.js`);
El app-Root-path utilise plusieurs techniques 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 dans le répertoire /var/www/
mais le module est installé dans ~/.nvm/v0.x.x/lib/node/
). Cela ne fonctionnera pas dans 100 % des cas, mais dans la plupart des cas.
Avantages et inconvénients
Fonctionne sans configuration dans la plupart des cas. Il fournit également quelques méthodes supplémentaires très pratiques (voir la page du projet). Le plus gros inconvénient est qu'il ne fonctionnera pas si :
- Vous utilisez un lanceur, comme pm2.
-
ET le module n'est pas installé dans le répertoire de votre application.
node_modules
(par exemple, si vous l'avez installé globalement)
Vous pouvez contourner ce problème en définissant un APP_ROOT_PATH
ou en appelant la variable environnementale .setPath()
sur le module, mais dans ce cas, il est probablement préférable d'utiliser l'option global
méthode.
Variable environnementale 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 au mieux pour vous. Si, en revanche, vous essayez de résoudre le problème du chargement fiable des modules d'application, je vous recommande vivement de vous pencher sur l'option NODE_PATH
variable environnementale.
Node's Système de modules recherche des modules dans différents endroits. L'un de ces lieux est l'endroit où process.env.NODE_PATH
points . Si vous définissez cette variable d'environnement, vous pouvez alors require
avec le chargeur de modules standard sans autre modification.
Par exemple, si vous définissez NODE_PATH
a /var/www/lib
le texte suivant fonctionnerait très bien :
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
Un bon moyen de le faire est d'utiliser npm
:
{
"scripts": {
"start": "NODE_PATH=. node app.js"
}
}
Vous pouvez maintenant démarrer votre application avec npm start
et vous êtes en or. Je combine ça avec mon enforce-node-path qui empêche le chargement accidentel de l'application sans le module NODE_PATH
set. Pour encore plus de contrôle sur l'application des variables environnementales, voir checkenv .
Un "gotcha" : NODE_PATH
doit être fixé à l'extérieur de de l'application du nœud. Vous ne pouvez pas faire quelque chose comme process.env.NODE_PATH = path.resolve(__dirname)
car le chargeur de modules met en cache la liste des répertoires qu'il va rechercher avant l'exécution de votre application.
[ajouté le 4/6/16] Un autre module très prometteur qui tente de résoudre ce problème est le suivant ondulé .
__dirname
n'est pas global ; il est local au module actuel, donc chaque fichier a sa propre valeur locale, différente.
Si vous voulez le répertoire racine du processus en cours, vous voudrez probablement utiliser process.cwd()
.
Si vous voulez de la prévisibilité et de la fiabilité, vous devez probablement exiger de votre application qu'une certaine variable d'environnement soit définie. Votre application recherche MY_APP_HOME
(ou autre) et s'il est là, et que l'application existe dans ce répertoire, alors tout va bien. Si elle n'est pas définie ou si le répertoire ne contient pas votre application, elle doit sortir avec une erreur invitant l'utilisateur à créer la variable. Elle pourrait être définie dans le cadre d'un processus d'installation.
Vous pouvez lire les variables d'environnement dans node avec quelque chose comme process.env.MY_ENV_VARIABLE
.
1- créer un fichier dans le projet Root l'appeler settings.js
2- dans ce fichier, ajoutez ce code
module.exports = {
POST_MAX_SIZE : 40 , //MB
UPLOAD_MAX_FILE_SIZE: 40, //MB
PROJECT_DIR : __dirname
};
3- dans node_modules créez un nouveau module nommé "settings" et dans le module index.js écrivez ce code :
module.exports = require("../../settings");
4- et à chaque fois que vous voulez le répertoire de votre projet, utilisez simplement
var settings = require("settings");
settings.PROJECT_DIR;
de cette façon, vous aurez tous les répertoires du projet relatifs à ce fichier ;)
Le moyen le 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 voulez vérifier ce qui précède
Disons que vous voulez faire une vérification croisée process.env.PWD
avec les paramètres de votre application node.js. Si vous souhaitez que des tests d'exécution vérifient la validité de l'application node.js, vous pouvez utiliser les paramètres de l'application. process.env.PWD
vous pouvez le vérifier avec ce code (que j'ai écrit et qui semble bien fonctionner). Vous pouvez croiser 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
- Réponses précédentes
- Plus de réponses