590 votes

Quelle est la différence entre __dirname et ./ dans node.js ?

Lorsque l'on programme en Node.js et que l'on fait référence à des fichiers qui sont situés quelque part par rapport à votre répertoire actuel, y a-t-il une raison d'utiliser la balise __dirname au lieu d'une simple variable ./ ? J'ai utilisé ./ jusqu'à présent dans mon code et je viens de découvrir l'existence de __dirname et je voudrais savoir s'il serait judicieux de convertir mes ./ en ./ et, le cas échéant, pourquoi ce serait une bonne idée.

67 votes

Tl;dr : Donc, fondamentalement, la différence est que './' et 'process.cwd()' font référence au répertoire courant du terminal appelant le script, alors que le '__dirname' fait référence au répertoire dans lequel le script est stocké.

9 votes

Sauf quand . est utilisé à l'intérieur de require . Le chemin à l'intérieur require est toujours relative au fichier contenant l'appel à require .

944voto

user1334007 Points 1088

L'essentiel

Dans Node.js, __dirname est toujours le répertoire dans lequel réside le script en cours d'exécution ( ver esto ). Ainsi, si vous avez tapé __dirname en /d1/d2/myscript.js la valeur serait /d1/d2 .

En revanche, . vous donne le répertoire à partir duquel vous avez exécuté la commande node dans votre fenêtre de terminal (c'est-à-dire votre répertoire de travail) lorsque vous utilisez des bibliothèques telles que path y fs . Techniquement, il s'agit au départ de votre répertoire de travail, mais il peut être modifié à l'aide de la commande process.chdir() .

L'exception est lorsque vous utilisez . con require() . Le chemin à l'intérieur require est toujours relative au fichier contenant l'appel à require .

Par exemple...

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 le faites

cd /dir1/dir2
node pathtest.js

vous obtenez

. = /dir1/dir2
__dirname = /dir1/dir2

Votre répertoire de travail est /dir1/dir2 donc c'est ce que . se résout. Puisque pathtest.js est situé à /dir1/dir2 c'est ce que __dirname se 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 donc c'est ce que . résolu à le faire, mais __dirname se résout toujours à /dir1/dir2 .

Utilisation de . à l'intérieur de require ...

Si à l'intérieur dir2/pathtest.js vous avez un require pour inclure un fichier dans dir1 vous toujours faire

require('../thefile')

car 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.

41 votes

IMO, cette explication est un peu plus claire que celle de la réponse acceptée (vous savez, "le répertoire courant" est un peu ambigu là).

6 votes

Je suis d'accord. Je vais modifier la réponse acceptée. Gardez à l'esprit que cette réponse a été ajoutée 2,5 ans après l'acceptation de la réponse originale, et que je ne m'en aperçois que maintenant (encore 2 ans plus tard) :) Mieux vaut tard que jamais !

17 votes

Il convient de noter que ./ n'est pas toujours le répertoire à partir duquel le nœud a été lancé. Il commence de cette façon, mais peut être modifié via le bouton process.chdir() . Donc, ./ est toujours le répertoire de travail actuel, qui est généralement le répertoire à partir duquel le noeud a été lancé, à moins que votre code n'ait explicitement changé le répertoire de travail.

161voto

DeaDEnD Points 6890

./ fait référence au répertoire de travail actuel, sauf dans le cas de l'option require() fonction. Lorsque vous utilisez require() il se traduit par ./ dans le répertoire du fichier courant appelé. __dirname est toujours le répertoire du fichier courant.

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 en /home/user/dir et exécuter node dir.js Je vais prendre

{ hello: 'world' }
text file

Mais quand je lance le même script 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)

Utilisation de ./ a travaillé avec require mais pas pour fs.readFileSync . C'est parce que pour fs.readFileSync , ./ se traduit par le cwd (dans ce cas-ci /home/user/ ). Et /home/user/files/somefile.txt n'existe pas.

0 votes

Oh je pensais que __dirname était le répertoire de travail actuel... merci pour la clarification !

1 votes

Existe-t-il un moyen de référencer le répertoire de travail de l'application avec fs ? Par exemple, j'essaie de charger un fichier à partir du répertoire de travail. /movies mais comme mon module est dans un fichier /custom_modules/ , __dirname essaie d'attraper le film de , /custom_modules/movies

4 votes

Vous pouvez utiliser ./ o process.cwd() . voir nodejs.org/api/process.html#process_process_cwd

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X