A essência
No Node.js, __dirnameé sempre o diretório em que o script atualmente em execução reside ( veja isso ). Então, se você digitou __dirnameem /d1/d2/myscript.js, o valor seria /d1/d2.
Por outro lado, .fornece o diretório a partir do qual você executou o nodecomando na janela do terminal (ou seja, o diretório de trabalho) quando você usa bibliotecas como pathe fs. Tecnicamente, ele começa como seu diretório de trabalho, mas pode ser alterado usando process.chdir().
A exceção é quando você usa .com require(). O caminho interno requireé sempre relativo ao arquivo que contém a chamada para require.
Por exemplo...
Digamos que sua estrutura de diretórios seja
/dir1
/dir2
pathtest.js
e pathtest.jscontém
var path = require("path");
console.log(". = %s", path.resolve("."));
console.log("__dirname = %s", path.resolve(__dirname));
e você faz
cd /dir1/dir2
node pathtest.js
você recebe
. = /dir1/dir2
__dirname = /dir1/dir2
Seu diretório de trabalho é /dir1/dir2o que .resolve. Desde que pathtest.jsestá localizado em /dir1/dir2que é o que __dirnameresolve também.
No entanto, se você executar o script a partir de /dir1
cd /dir1
node dir2/pathtest.js
você recebe
. = /dir1
__dirname = /dir1/dir2
Nesse caso, seu diretório de trabalho era /dir1e foi assim que .resolveu, mas __dirnameainda resolve /dir1/dir2.
Usando .dentro require...
Se dentro de dir2/pathtest.jsvocê tiver uma requirechamada para incluir um arquivo dentro, dir1você sempre faria
require('../thefile')
porque o caminho interno requireé sempre relativo ao arquivo no qual você está chamando. Não tem nada a ver com o seu diretório de trabalho.