Lors de la programmation dans Node.js et du référencement de fichiers situés quelque part par rapport à votre répertoire actuel, existe-t-il une raison d'utiliser la variable __dirname
au lieu d'un simple ./
? J'ai utilisé ./ jusqu'à présent dans mon code et je viens de découvrir l'existence de __dirname
, et je veux essentiellement savoir s'il serait judicieux de convertir mon ./ à cela, et si oui, pourquoi serait une bonne idée.
Dans Node.js, __dirname
est toujours le répertoire dans lequel réside le script en cours d'exécution ( voir ceci ). Donc, si vous tapez __dirname
dans /d1/d2/myscript.js
, la valeur sera /d1/d2
.
Par contre, .
vous donne le répertoire à partir duquel vous avez exécuté la commande node
dans la fenêtre de votre terminal (c’est-à-dire votre répertoire de travail) lorsque vous utilisez des bibliothèques telles que path
et fs
. Techniquement, cela commence comme votre répertoire de travail, mais vous pouvez le changer avec process.chdir()
.
L'exception est lorsque vous utilisez .
avec require()
. Le chemin à l'intérieur de require
est toujours relatif au fichier contenant l'appel à require
.
Disons que votre structure de répertoire est
/dir1
/dir2
pathtest.js
et pathtest.js
contient
var path = require("path");
console.log(". = %s", path.resolve("."));
console.log("__dirname = %s", path.resolve(__dirname));
et vous faites
cd /dir1/dir2
node pathtest.js
vous obtenez
. = /dir1/dir2
__dirname = /dir1/dir2
Votre répertoire de travail est /dir1/dir2
alors c'est ce que .
résout. Puisque pathtest.js
se trouve dans /dir1/dir2
, c'est ce que __dirname
résout également.
Cependant, si vous exécutez le script à partir de /dir1
cd /dir1
node dir2/pathtest.js
vous obtenez
. = /dir1
__dirname = /dir1/dir2
Dans ce cas, votre répertoire de travail était /dir1
alors c'est ce que .
a résolu, mais __dirname
est toujours résolu en /dir1/dir2
.
.
dans require
...Si à l'intérieur de dir2/pathtest.js
vous avez un appel require
afin d'inclure un fichier à l'intérieur de dir1
vous devriez toujours faire
require('../thefile')
parce que le chemin à l'intérieur de require
est toujours relatif au fichier dans lequel vous l'appelez. Cela n'a rien à voir avec votre répertoire de travail.
./
fait référence au répertoire de travail en cours, sauf dans la fonction require()
. Lorsque vous utilisez require()
, il convertit ./
dans le répertoire du fichier en cours appelé. __dirname
est toujours le répertoire du fichier actuel.
Par exemple, avec la structure de fichier suivante
/home/user/dir/files/config.json
{
"hello": "world"
}
/home/user/dir/files/somefile.txt
text file
/home/user/dir/dir.js
var fs = require('fs');
console.log(require('./files/config.json'));
console.log(fs.readFileSync('./files/somefile.txt', 'utf8'));
Si je cd
dans /home/user/dir
et que je lance node dir.js
je vais obtenir
{ hello: 'world' }
text file
Mais quand je lance le même script à partir de /home/user/
je reçois
{ hello: 'world' }
Error: ENOENT, no such file or directory './files/somefile.txt'
at Object.openSync (fs.js:228:18)
at Object.readFileSync (fs.js:119:15)
at Object.<anonymous> (/home/user/dir/dir.js:4:16)
at Module._compile (module.js:432:26)
at Object..js (module.js:450:10)
at Module.load (module.js:351:31)
at Function._load (module.js:310:12)
at Array.0 (module.js:470:10)
at EventEmitter._tickCallback (node.js:192:40)
Utiliser ./
a fonctionné avec require
mais pas pour fs.readFileSync
. En effet, pour fs.readFileSync
, ./
est traduit en cwd (dans ce cas /home/user/
). Et /home/user/files/somefile.txt
n'existe pas.