Existe-t-il un meilleur moyen que process.cwd()
pour 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.
Il existe plusieurs façons d'aborder cette question, chacune ayant ses avantages et ses inconvénients :
De http://nodejs.org/api/modules.html :
Lorsqu'un fichier est exécuté directement depuis Node,
require.main
est défini comme sonmodule
. Cela signifie que vous pouvez déterminer si un fichier a été exécuté directement en testantrequire.main === module
.Comme
module
fournit une propriétéfilename
(normalement équivalente à__filename
), le point d'entrée de l'application actuelle peut être obtenu en vérifiantrequire.main.filename
.
Donc si vous voulez le répertoire de base de votre application, vous pouvez le faire :
var path = require('path');
var appDir = path.dirname(require.main.filename);
Cette méthode fonctionne très bien la plupart du temps, mais si vous exécutez votre application avec un lanceur comme pm2 ou si vous exécutez des tests mocha, cette méthode échouera.
Node possède un 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 quel que soit le nom du fichier principal de votre application), 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');
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.
Ceci renvoie le répertoire de travail actuel. Pas fiable du tout, car il dépend entièrement du répertoire à partir duquel le processus a été lancé :
$ 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
Pour résoudre ce problème, j'ai créé un module node 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 tourne dans /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.
Fonctionne sans configuration dans la plupart des cas. Fournit également quelques méthodes pratiques supplémentaires (voir la page du projet). Le plus gros inconvénient est qu’il ne fonctionnera pas si :
node_modules
de votre application (par exemple, si vous l'avez installé globalement).Vous pouvez contourner ce problème en définissant une variable d'environnement APP_ROOT_PATH
, ou en appelant .setPath()
sur le module, mais dans ce cas, il est probablement préférable d'utiliser la méthode global
.
Si vous cherchez un moyen de déterminer le chemin de la racine de l'application en cours, l'une des solutions ci-dessus vous conviendra probablement mieux. Si, par contre, vous essayez de résoudre le problème du chargement fiable des modules de l'application, je vous recommande vivement d'étudier la variable d'environnement NODE_PATH
.
Le [système de modules] de Node (https://nodejs.org/api/modules.html) recherche les modules à différents endroits. L'un de ces emplacements est celui où pointe process.env.NODE_PATH
. Si vous définissez cette variable d'environnement, vous pouvez demander des modules avec le chargeur de modules standard sans aucun autre changement.
Par exemple, si vous définissez NODE_PATH
à /var/www/lib
, ce qui suit fonctionnera très bien :
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
Un bon moyen de faire cela est d'utiliser npm
:
"scripts": {
"start": "NODE_PATH=. node app.js"
}
Maintenant, vous pouvez démarrer votre application avec npm start
et c'est bon. Je combine ceci avec mon module enforce-node-path, qui empêche le chargement accidentel de l'application sans que NODE_PATH
soit défini. Pour encore plus de contrôle sur l'application des variables environnementales, voir checkenv.
Un problème : NODE_PATH
doit être défini en dehors** de l'application node. 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 chercher avant que votre application ne s'exécute.
[ajouté le 4/6/16] Un autre module très prometteur qui tente de résoudre ce problème est wavy.
__dirname
n'est pas un 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é, alors vous devez probablement exiger de votre application qu'une certaine variable d'environnement soit définie. Votre application cherche MY_APP_HOME
(ou autre) et si elle y est, et que l'application existe dans ce répertoire, tout va bien. Si elle n'est pas définie ou si le répertoire ne contient pas votre application, l'application doit sortir avec une erreur demandant à l'utilisateur de créer la variable. Elle peut ê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 à la racine du projet appelé 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- 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 ;)