__dirnameを使用したpath.joinとpath.resolve


141

Node.jsで絶対パスを解決するために両方 path.joinを使用する場合に違いはありますか?path.resolve__dirname

このように使用する場合、そのうちの1つを優先する必要がありますか(絶対パスの解像度はユースケースの90%です)?

すなわち

const absolutePath = path.join(__dirname, some, dir);

対

const absolutePath = path.resolve(__dirname, some, dir);

どちらの方法でもパスを正規化します。

受け入れられた答えが間違っているため、これはこの質問の複製ではありません。


この質問はメタで議論されています
— Nino Filiu

これはあなたの質問に答えますか?path.resolveとpath.joinの呼び出しの違いは?
— user5532169

回答:


151

はい、機能には違いがありますが、この場合の使用方法は同じ結果になります。

path.join2つのパスをマージして正規化されたパスを返します。絶対パスを返すことができますが、常にそうであるとは限りません。

例えば:

path.join('app/libs/oauth', '/../ssl')

解決する app/libs/ssl

path.resolve一方、は絶対パスに解決されます。

たとえば、次を実行すると:

path.resolve('bar', '/foo');

返されるパス/fooは、構築可能な最初の絶対パスであるためです。

ただし、実行すると:

path.resolve('/bar/bae', '/foo', 'test');

返されるパス/foo/testは、右から左に形成できる最初の絶対パスであるため、再度になります。

ルートディレクトリを指定するパスを指定しない場合、resolve関数に指定されたパスが現在の作業ディレクトリに追加されます。したがって、作業ディレクトリが/home/mark/project/次の場合:

path.resolve('test', 'directory', '../back');

解決する

/home/mark/project/test/back

Using __dirnameは、ソースファイルを含むディレクトリへの絶対パスです。を使用した場合、path.resolveまたはpath.joinと同じパスを指定すると、同じ結果が返されます__dirname。そのような場合、それは本当に好みの問題です。


25
Nit:__dirnameは、現在作業中のディレクトリではなく、実行中のソースファイルを含むディレクトリへの絶対パスです。前者は常に同じです(ファイルを移動しない限り)。後者はプロセス全体のパラメーターであり、ノードの起動方法と、ノードを変更したかどうかによって異なります。
— josh3736 2017年

2
だから、差がない__dirnameとはpath.resolve(__dirname)?
— georaldc 2017

1
@georaldc:見つかった:node <<< "path = require( 'path'); console.log(__ dirname); console.log(path.resolve(__ dirname))"
— Colin

8
私はそれを言うのが嫌いですが、この答えは本当に私には意味がありません、そして私はいくつかの説明をいただければ幸いです。あなたはそれを発言path.resolve('/bar/bae', '/foo', 'test');するので、基本的に破棄し、最初の引数を/foo/test「右から左に形成することができる最初の絶対パスである」しかし、あなたは説明しなかった理由を、私は本当に仕事でロジックを理解していないので、。私があなたの例で使用している架空のディレクトリ構造をまったく見ないので、なぜ/bar/bae/foo/testが無効であるのか理解できません。
— temporary_user_name

3
@temporary_user_nameのpath.resolveここでの動作は正解です。path.resolve右端の引数から操作し、引数リストを左に移動して、絶対パス(つまり、ルートディレクトリで始まるパス/または[Windowsでは]ドライブ文字)が作成され、そのパスが返されます。/bar/baeその時点までに、それはすでに絶対パス/foo/testを持っているので無視します。
— ジェイミーライディング

23
const absolutePath = path.join(__dirname, some, dir);

対

const absolutePath = path.resolve(__dirname, some, dir);

path.join連結であろう__dirname値と連結現在のファイルのディレクトリ名であるsomeとdirプラットフォーム固有のセパレータ。

どこに

path.resolve処理し__dirname、someそしてdirつまりは、それを処理することによって、それを付加右から左に。

ルートパスの値someまたはdirルートパスに対応する値の場合、前のパスは省略され、ルートと見なして残りのプロセスが処理されます

概念をよりよく理解するために、次のように両方をもう少し詳しく説明しましょう。

二つの異なる方法またはnodejsによって提供されるパスモジュールの関数です。path.joinpath.resolve

どちらもパスのリストを受け入れますが、違いは結果、つまりこれらのパスの処理方法にあります。

path.joinプラットフォーム固有の区切り文字を区切り文字として使用して、指定されたすべてのパスセグメントを連結し、結果のパスを正規化します。一方、path.resolve()プロセスの右からの絶対パスが構築されるまで、付加後続の各パスで、左へのパスの配列。

引数が指定されていない場合

次の例は、両方の概念を明確に理解するのに役立ちます:-

私のファイル名はindex.jsで、現在の作業ディレクトリはE:\MyFolder\Pjtz\node

const path = require('path');

console.log("path.join() : ", path.join());
// outputs .
console.log("path.resolve() : ", path.resolve());
// outputs current directory or equalent to __dirname

結果

λ node index.js
path.join() :  .
path.resolve() :  E:\MyFolder\Pjtz\node

path.resolve()メソッドは絶対パスを出力しpath.join()ます。何も提供されていない場合、現在の作業ディレクトリを表す

いくつかのルートパスが引数として渡されたとき

const path=require('path');

console.log("path.join() : " ,path.join('abc','/bcd'));
console.log("path.resolve() : ",path.resolve('abc','/bcd'));

結果i

λ node index.js
path.join() :  abc\bcd
path.resolve() :  E:\bcd

path.join()path.resolve()絶対パスが構築されるまで後続の各パスが前に付けられて、パスのシーケンスを右から左に処理しながら、プラットフォーム固有のセパレーターのみで入力リストを連結します。


問題は、特に__dirname を使用したpath.join とpath.resolveに関するものでした。
— Estus Flask 2017

私はあなたのコメントに基づいて回答を更新しました
— -samuelj90

3

ドキュメントからpath.resolve:

結果のパスは正規化され、パスがルートディレクトリに解決されない限り、末尾のスラッシュは削除されます。

しかし、path.joinスラッシュが続く

そう

__dirname = '/';
path.join(__dirname, 'foo/'); // '/foo/'
path.resolve(__dirname, 'foo/'); // '/foo'

この文脈で「正規化」という言葉はどういう意味ですか?
— アポロ2018

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.