Node.jsのprocess.cwd()で作業ディレクトリ取得
Node.jsで作業ディレクトリの絶対パスを取得するには、process.cwd()を使います。戻り値は「Node.jsを起動したディレクトリ」であり、実行しているスクリプトファイルの場所ではありません。この違いを押さえておくと、パス関連のトラブルの大半を避けられます。
こんな悩みを解決します
ENOENT: no such file or directoryでファイルを読み込めないエラー- 手元では動くのにサーバーやCIで動かない問題
- プログラムの基準ディレクトリが分からない状況
process.cwd()と__dirnameの使い分け
process.cwd()とは
process.cwd()は、現在の作業ディレクトリ(カレントディレクトリ)の絶対パスを文字列で返すメソッドです。作業ディレクトリとは、ターミナルで「今いる場所」のことです。cwdは current working directory の略です。
process.cwd()
返ってくる値は実行環境によって次のように変わります。
- Windows:
C:\Users\taro\projectのような形式 - macOS・Linux:
/home/taro/projectのような形式
ファイルの読み書きやパスの組み立てでは、基準になるディレクトリを把握することが重要です。process.cwd()をログに出せば、プログラムがどこを基準に動いているかをすぐに確認できます。
戻り値は「スクリプトの場所」ではない
process.cwd()が返すのは、nodeコマンドを実行した場所です。スクリプトファイルが置かれている場所とは関係ありません。
たとえば、/home/taro/projectにいる状態でsrcフォルダ内のスクリプトを実行したとします。この場合、process.cwd()が返すのは/home/taro/projectです。スクリプトがある/home/taro/project/srcにはなりません。
同じスクリプトでも、どこから実行するかで結果が変わります。これが「自分のPCでは動くのに、別の環境では動かない」という現象の主な原因です。
スクリプトの場所を知りたいときは__dirname
スクリプトファイル自身のあるディレクトリが必要な場合は、__dirnameを使います。process.cwd()との違いは次のとおりです。
| 項目 | process.cwd() |
__dirname |
|---|---|---|
| 意味 | Node.jsを起動したディレクトリ | 実行中のファイルがあるディレクトリ |
| 実行場所による変化 | 変わる | 変わらない |
| 向いている用途 | 実行したプロジェクトのルートを基準にしたい場合 | スクリプトと同じ場所のファイルを参照したい場合 |
ES Modules(import構文を使う形式)では__dirnameが使えません。Node.js 20.11以降ならimport.meta.dirnameが代わりになります。それ以前のバージョンでは、import.meta.urlからfileURLToPathで変換します。
相対パスでファイルが見つからない原因
fs.readFile('./data.json')のような相対パスは、スクリプトの場所ではなくprocess.cwd()を基準に解決されます。そのため、実行場所が変わると同じコードでもENOENTになります。
対処法は、基準を明示した絶対パスを組み立てることです。
- スクリプトと同じ場所にあるファイル:
path.join(__dirname, 'data.json')で指定 - 実行したプロジェクトのルートにあるファイル:
path.join(process.cwd(), 'data.json')で指定
path.joinやpath.resolveを使えば、/と\の違いを意識せずに済みます。文字列を+で連結するより安全です。path.resolve('data.json')は、process.cwd()を基準にした絶対パスを返します。
使い分けの目安
- 設定ファイルやテンプレートなど、スクリプトに同梱するファイル:
__dirname - CLIツールが、利用者のプロジェクト内のファイルを探す場合:
process.cwd() - 実行場所に左右されたくない処理全般:
__dirnameを基準にした指定
注意点
作業ディレクトリが意図せず変わるケースは次のとおりです。
process.chdir()の呼び出しによる、以降のprocess.cwd()の値の変化- VS Codeのデバッグ実行、cron、タスクスケジューラ、Dockerの
WORKDIRなど、手元の実行と起動時の作業ディレクトリが異なる環境
動作が環境ごとに食い違うときは、まずprocess.cwd()をログに出力して、実際の基準位置を確認してください。
まとめ
process.cwd()の戻り値は、Node.jsを起動したディレクトリの絶対パス- スクリプト自身の場所が必要なときの選択肢は
__dirname - 相対パスの基準は
process.cwd()で、実行場所が変わるとエラーになること path.joinやpath.resolveによるパスの組み立てで、環境差のトラブルを軽減
