Wat is het verschil tussen __dirname en ./ in node.js?

Is er een reden om de variabele __dirnamete gebruiken in plaats van alleen een gewone ./? Ik heb tot nu toe ./ in mijn code gebruikt en heb zojuist het bestaan van __dirnameontdekt, en wil in wezen weten of het slim zou zijn om mijn ./’s daarnaar te converteren, en zo ja , waarom zou dat een slim idee zijn.


Antwoord 1, autoriteit 100%

De essentie

In Node.js is __dirnamealtijd de map waarin het momenteel uitgevoerde script zich bevindt (zie dit). Dus als je __dirnametypt in /d1/d2/myscript.js, zou de waarde /d1/d2zijn.

In tegenstelling, .geeft je de directory van waaruit je de opdracht nodehebt uitgevoerd in je terminalvenster (dwz je werkdirectory) wanneer je bibliotheken zoals pathen fs. Technisch gezien begint het als uw werkmap, maar kan worden gewijzigd met process.chdir().

De uitzondering is wanneer u .gebruikt met require(). Het pad binnen requireis altijd relatief ten opzichte van het bestand dat de aanroep naar requirebevat.

Bijvoorbeeld…

Stel dat uw directorystructuur is

/dir1
  /dir2
    pathtest.js

en pathtest.jsbevat

var path = require("path");
console.log(". = %s", path.resolve("."));
console.log("__dirname = %s", path.resolve(__dirname));

en jij ook

cd /dir1/dir2
node pathtest.js

je krijgt

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

Je werkmap is /dir1/dir2dus dat is waar .naar verwijst. Aangezien pathtest.jszich in /dir1/dir2bevindt, is dat ook waar __dirnamenaar verwijst.

Als u het script echter uitvoert vanuit /dir1

cd /dir1
node dir2/pathtest.js

je krijgt

. = /dir1
__dirname = /dir1/dir2

In dat geval was uw werkdirectory /dir1dus dat is waar .naar is opgelost, maar __dirnamewordt nog steeds omgezet in /dir1/dir2.

Gebruik .binnen require

Als je in dir2/pathtest.jseen require-aanroep hebt om een bestand in dir1op te nemen, zou je altijddoen

require('../thefile')

omdat het pad binnen requirealtijd relatief is ten opzichte van het bestand waarin je het aanroept. Het heeft niets te maken met je werkmap.


Antwoord 2, autoriteit 18%

./verwijst naar de huidige werkmap, behalve in de functie require(). Bij gebruik van require(), vertaalt het ./naar de directory van het huidige bestand dat wordt aangeroepen. __dirnameis altijd de directory van het huidige bestand.

Bijvoorbeeld met de volgende bestandsstructuur

/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'));

Als ik cdin /home/user/diren node dir.jsuitvoer, krijg ik

{ hello: 'world' }
text file

Maar als ik hetzelfde script uitvoer vanuit /home/user/krijg ik

{ 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)

Het gebruik van ./werkte met requiremaar niet voor fs.readFileSync. Dat komt omdat voor fs.readFileSync./zich vertaalt in de cwd (in dit geval /home/user/). En /home/user/files/somefile.txtbestaat niet.

Other episodes