Solución:
La esencia
En Node.js, __dirname
es siempre el directorio en el que reside el script que se está ejecutando actualmente (ver esto). Entonces, si escribiste __dirname
dentro /d1/d2/myscript.js
, el valor sería /d1/d2
.
Por el contrario, .
le da el directorio desde el que ejecutó el node
comando en la ventana de su terminal (es decir, su directorio de trabajo) cuando usa bibliotecas como path
y fs
. Técnicamente, comienza como su directorio de trabajo, pero se puede cambiar usando process.chdir()
.
La excepción es cuando usa .
con require()
. El camino interior require
siempre es relativo al archivo que contiene la llamada a require
.
Por ejemplo…
Digamos que su estructura de directorio es
/dir1
/dir2
pathtest.js
y pathtest.js
contiene
var path = require("path");
console.log(". = %s", path.resolve("."));
console.log("__dirname = %s", path.resolve(__dirname));
y lo hace
cd /dir1/dir2
node pathtest.js
usted obtiene
. = /dir1/dir2
__dirname = /dir1/dir2
Tu directorio de trabajo es /dir1/dir2
entonces eso es lo que .
resuelve. Ya que pathtest.js
Se encuentra en /dir1/dir2
eso es lo que __dirname
también se resuelve.
Sin embargo, si ejecuta el script desde /dir1
cd /dir1
node dir2/pathtest.js
usted obtiene
. = /dir1
__dirname = /dir1/dir2
En ese caso, su directorio de trabajo era /dir1
entonces eso es lo que .
resuelto a, pero __dirname
todavía se resuelve a /dir1/dir2
.
Utilizando .
dentro require
…
Si adentro dir2/pathtest.js
usted tiene un require
llamar para incluir un archivo dentro dir1
lo harías siempre hacer
require('../thefile')
porque el camino dentro require
siempre es relativo al archivo en el que lo está llamando. No tiene nada que ver con su directorio de trabajo.
./
se refiere al directorio de trabajo actual, excepto en el require()
función. Cuando usas require()
, se traduce ./
al directorio del archivo actual llamado. __dirname
es siempre el directorio del archivo actual.
Por ejemplo, con la siguiente estructura de archivos
/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 yo cd
dentro /home/user/dir
y correr node dir.js
Voy a conseguir
{ hello: 'world' }
text file
Pero cuando ejecuto el mismo script desde /home/user/
yo obtengo
{ 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)
Utilizando ./
trabajado con require
pero no para fs.readFileSync
. Eso es porque para fs.readFileSync
, ./
se traduce en cwd (en este caso /home/user/
). Y /home/user/files/somefile.txt
no existe.