同じNode.jsスクリプトなのに、起動する場所を変えただけで別のファイルを読んでしまうことがあります。fs.readFile('./message.txt')の基準は、スクリプトの保存場所ではなくプロセスの作業ディレクトリです。
2026年10月26日、macOS 27.0.1・Node.js v24.22.1で実測しました。ここではローカルのES Modules(.mjs)を扱います。Windows、CommonJS、バンドラー経由の実行は試していません。
同じ名前のファイルを二つ用意する
新しい練習フォルダに、次の構成を作ります。既存プロジェクトへ上書きせず、空の場所で試してください。
practice/
├── message.txt 内容は ROOT
└── app/
├── message.txt 内容は APP
└── read.mjs
read.mjsは次のコードです。ファイルの読み込み方法だけを二通りに分けます。
import { readFile } from 'node:fs/promises';
console.log('relative:', (await readFile('./message.txt', 'utf8')).trim());
console.log('module:', (await readFile(new URL('./message.txt', import.meta.url), 'utf8')).trim());
new URL('./message.txt', import.meta.url)は、このモジュールのURLを基準に隣のファイルを指定します。今回のNode.jsのreadFileはfile URLのオブジェクトを受け取れるので、文字列のパスへ変換せず渡しています。
appの中から起動した結果
appディレクトリを作業場所にして実行します。
node read.mjs
実測した標準出力です。終了コードは0でした。
relative: APP
module: APP
作業場所とモジュールの場所が同じなので、どちらもapp/message.txtを読みます。この実行だけでは基準の違いは見えません。
親のpracticeから起動すると変わる
今度はpracticeディレクトリを作業場所にして、同じファイルを実行します。
node app/read.mjs
コードもファイルの中身も変えていません。実測結果は次のとおりで、終了コードは0でした。
relative: ROOT
module: APP
相対パス文字列で渡した方はpractice/message.txtを読み、モジュールのURLを基準にした方はapp/message.txtを読みました。誤ったファイルでも読み込み自体が成功すると、ENOENTのようなエラーは出ません。
親のファイルがなければENOENTになる
次に、親のpractice/message.txtだけを取り除いて同じ実行を試しました。app/message.txtは残しています。標準出力は空で、標準エラー出力には次のメッセージがあり、終了コードは1でした。
Error: ENOENT: no such file or directory, open './message.txt'
上のread.mjsでは一つ目のawaitが失敗するため、二つ目の読み込みまでは進んでいません。この結果を「URLで指定しても失敗した」とは読めません。
どちらを基準にするかを用途で決める
- スクリプトに同梱したテンプレートや固定データを読むなら、モジュールを基準にする設計が候補です。
- 利用者が作業中のフォルダに置いた入力を読むなら、作業ディレクトリを基準にする設計が候補です。
相対パスをすべてURLへ置き換えればよい、という話ではありません。起動場所を変えたときも同梱データを読みたいのか、起動した場所の入力を読みたいのかを決めます。
Node.js公式:ファイルパスでは文字列の相対パスを作業ディレクトリ基準で扱うこと、Node.js公式:ES Modulesではimport.meta.urlを使う読み込み例を確認できます。この記事の結果は上記の実測環境に限り、ブラウザのfetchやimport指定子全般へは拡張しません。
未経験者向けの体験版を公開しています
- ▶ ライブデモ(インストール不要・無料)→ https://trial-web-ayies128s-projects.vercel.app/?ref=qiita
- 無料体験版(git clone して手元で動かす・⭐ Star もよろしくお願いします)→ https://github.com/ayies128/next-ai-camp-trial
- YouTube『AIエンジニア情報局』(AI×開発ニュースを1本5分で)→ https://www.youtube.com/channel/UC1rXVD9WYsQPQEWZyd-A1KA/?ref=qiita
※ 中上級者には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。