node.jsの__dirnameと./の違いは何ですか?


498

Node.jsでプログラミングし、現在のディレクトリのどこかにあるファイルを参照する場合__dirname、通常の変数ではなく変数を使用する理由はあります./か?私はこれまで./をコードで使用していて、の存在を発見したばかり__dirnameであり、本質的に./を。。


47
tl; dr:つまり、基本的に、「./」と「process.cwd()」はスクリプトを呼び出している端末の現在のディレクトリを参照し、「__ dirname」はスクリプトが存在するディレクトリを参照するという違いです保管。
— 今村桂

1
.内部で使用される場合を除きrequireます。内部のパスrequireは、常にへの呼び出しを含むファイルからの相対パスrequireです。
— Govind Rai

回答:


814

要旨

Node.jsでは、__dirname常に、現在実行中のスクリプトが存在するディレクトリです(これを参照)。したがって、と入力__dirnameした/d1/d2/myscript.js場合、値はになります/d1/d2。

対照的に、やなどのライブラリを使用すると、ターミナルウィンドウでコマンド.を実行したnodeディレクトリ(つまり、作業ディレクトリ)が表示されます。技術的には、作業ディレクトリとして開始されますが、を使用して変更できます。pathfsprocess.chdir()

例外は、で使用.する場合ですrequire()。内部のパスrequireは、常にへの呼び出しを含むファイルからの相対パスrequireです。

例えば...

あなたのディレクトリ構造が

/dir1
  /dir2
    pathtest.js

とpathtest.jsが含まれています

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

そしてあなたはする

cd /dir1/dir2
node pathtest.js

あなたは得る

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

あなたの作業ディレクトリは/dir1/dir2それが.解決するものです。にあるのでpathtest.js、/dir1/dir2それ__dirnameも解決されます。

ただし、スクリプトを /dir1

cd /dir1
node dir2/pathtest.js

あなたは得る

. = /dir1
__dirname = /dir1/dir2

その場合、あなたの作業ディレクトリは解決された/dir1ものでした.が、__dirnameそれでも解決され/dir1/dir2ます。

中を使っ.てrequire......

内部でファイルをインクルードdir2/pathtest.jsするrequire呼び出しがあるdir1場合は常に実行します

require('../thefile')

内部のパスrequireは常にそれを呼び出しているファイルからの相対パスだからです。作業ディレクトリとは関係ありません。


38
IMO、この説明は、受け入れられた回答からの説明よりも少し明確です(ご存知のように、「現在のディレクトリ」は少しあいまいです)。
— 具現化

5
同意する。受け付けた回答を変更します。この回答は、最初の回答が受け入れられてから2.5年後に追加されたものであり、私が気付いたのは今(2年後)だけです。:)遅くならない方がいいです!
— thisissami 2015

14
それはそれは注目に値します./ではありません常にノードがから開始されたことをディレクトリ。最初はその方法ですが、で変更できますprocess.chdir()。したがって、./コードは明示的に作業ディレクトリを変更しない限り、常に現在の作業ディレクトリです。これは通常、ノードが起動されたディレクトリノードです。
— gilly3

3
使い方について少し混乱しています。requireの内側のパスが、常に呼び出しているファイルからの相対パスである場合、パスはrequire( '../ dir1 / thefile')ではなくrequire( '../ thefile')でなければなりませんか?私は..パスの現在の位置をdir2からdir1にすでに1レベル戻すと思った。それでもdir1をパスに入れる必要がありますか、それとも何か理解できないのですか?
— andromada 2017

1
また../someDir、スクリプトで使用する必要があり、別のフォルダーからコマンドを実行する場合はどうすればよいでしょうか。
— cbdeveloper

154

./require()関数を除いて、現在の作業ディレクトリを参照します。を使用するとrequire()、./呼び出された現在のファイルのディレクトリに変換されます。__dirname常に現在のファイルのディレクトリです。

たとえば、次のファイル構造では

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

私の場合cdに/home/user/dirして実行しnode dir.js、私が取得します

{ hello: 'world' }
text file

しかし、同じスクリプトを実行すると/home/user/、

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

はで動作し./ましたrequireが、では動作しませんでしたfs.readFileSync。これは、for がcwd(この場合は)fs.readFileSyncに./変換されるためです/home/user/。そして/home/user/files/somefile.txt存在しません。


おお、私は__dirnameが現在の作業ディレクトリだと思った...明確化に感謝!
— thisissami

fsでアプリの作業ディレクトリを参照する方法はありますか?例えば、私は作業ディレクトリからファイルをロードしようとしている/moviesが、私のモジュールがファイルであることから/custom_modules/、__dirnameから映画をつかむしようとします/custom_modules/movies

2
./またはを使用できますprocess.cwd()。参照nodejs.org/api/process.html#process_process_cwd
— fent

ノードで同じように動作しますが、パッケージのbrowserifyビルドで問題が発生する可能性があるため、requireステートメントで./よりも__dirnameを使用することはお勧めできません。
— Jed Watson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.