読み込み中...

JavaScriptでパス取得を簡単に!5つの方法と使い方サンプルコード

JavaScriptでパス取得する5つの方法を習得しよう JS
この記事は約28分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

JavaScriptのパス取得は、ブラウザのURL処理とNode.jsのファイルシステム処理で使うAPIが分かれます。URLならURLwindow.location、ローカルファイルならnode:pathnode:fsを選ぶのが基本になります。

その違いを混同すると、ブラウザでrequireが使えない、Node.jsでwindowが見つからない、WindowsとmacOSで区切り文字がずれる、といった問題が起きますし、ここがポイントです。パス取得の使い方は、実行環境、対象がURLかファイルか、相対パスを解決する基準の順に整理すると判断しやすくなります。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

JavaScriptでパス取得とは

結論として、JavaScriptでパス取得を行うときは、ブラウザではURL文字列、Node.jsではファイルパス文字列を扱うと切り分けます。たとえばURLのパス部分だけなら、次のようにURLオブジェクトのpathnameを読むだけで取得できます。

const url = new URL('https://example.com/docs/guide/index.html?tab=path');
console.log(url.pathname);

結果: 期待される出力は/docs/guide/index.htmlです。クエリ文字列の?tab=pathpathnameに含まれません。

動作確認環境
  • JavaScript: ECMAScript 2024相当の構文
  • Node.js: 22 LTS系、node:pathnode:fs
  • ブラウザ: Google Chrome 126以降、Firefox 127以降、Safari 17以降
📖 この記事で学べること
  • JavaScriptでファイル名、拡張子、ディレクトリ名を取り出す考え方
  • Node.jsのpathモジュールを使うパス取得の使い方
  • ブラウザのwindow.locationURLによるURL解析
  • 相対パスと絶対パスを扱う際の注意点
  • ENOENTEACCESなどの代表的なエラーへの対処法

一般に、パスとはファイル、ディレクトリ、URL上のリソース位置を表す文字列です。JavaScriptから見たパス取得は、文字列を分割する処理だけで完結する場合もあれば、OSごとの差異を吸収するためにpath.dirname()path.resolve()を使う場合もあります。

そのため、同じ/path/to/file.txtのような文字列でも、ブラウザではURLの一部、Node.jsではファイルシステム上の位置として扱われます。初心者がつまずきやすいのは、ブラウザのJavaScriptでfsを呼び出そうとしたり、Node.js側でwindow.locationを参照したりする点です。

具体的には、ブラウザで現在ページの情報を読むならlocation.hreflocation.pathnamelocation.originを使いるのが基本です。一方、Node.jsでファイル名や親ディレクトリを求めるなら、公式ドキュメントのNode.js Path APIにあるpath.basename()path.extname()path.dirname()が候補になります。

これらのAPIを選ぶ前に、相対パスと絶対パスの違いも押さえる必要があります。相対パスは基準位置からの道筋を示し、絶対パスはルートやドライブから見た固定位置を示すため、パス取得の結果を保存処理やリンク生成に使うときの意味が変わりますが、これは押さえたい点です。

対象主なAPI実行環境戻り値の例注意点
現在URL全体location.hrefブラウザhttps://example.com/a/b.htmlクエリとハッシュを含みます
URLのパス部分location.pathnameブラウザ/a/b.htmlドメイン名は含みません
URL解析new URL()ブラウザ、Node.jsURLオブジェクト基準URLが必要な場面があります
ファイル名path.basename()Node.jsfile.txtブラウザではそのまま使えません
拡張子path.extname()Node.js.txtドットを含みます
親ディレクトリpath.dirname()Node.js/path/to末尾スラッシュの扱いに注意します
絶対パス化path.resolve()Node.js/home/app/file.txtカレントディレクトリの影響を受けます
パス結合path.join()Node.js/path/to/file.txt余分な区切り文字を正規化します
OS区切り文字path.sepNode.js/または表示用とURL用を混ぜないようにします
POSIX形式path.posixNode.js/a/bURL風のパスに近い形式です
Windows形式path.win32Node.jsC:abドライブ文字を扱えます
ディレクトリ一覧fs.readdir()Node.jsstring[]権限と存在確認が必要です
同期一覧fs.readdirSync()Node.jsstring[]処理をブロックします
ファイル状態fs.statSync()Node.jsStats存在しないパスで例外になります
ディレクトリ判定isDirectory()Node.jstrueシンボリックリンクでは別判断が必要です
存在確認fs.access()Node.jsエラーまたは成功確認後の状態変化に注意します
読み取り権限fs.constants.R_OKNode.js定数OSの権限設定に依存します
書き込み権限fs.constants.W_OKNode.js定数EACCESへの備えが必要です
末尾要素取得split()pop()共通file.txt空文字の混入に注意します
一部除外slice()共通配列負のインデックスを理解します
再結合join()共通/path/to区切り文字を明示します
正規表現分割/[\/]/共通配列バックスラッシュのエスケープが必要です
クエリ取得searchParamsブラウザ、Node.jsURLSearchParamsパス名とは別の領域です
ハッシュ取得location.hashブラウザ#sectionサーバーへ送信されない部分です
オリジン取得location.originブラウザhttps://example.comプロトコルとホストを含みます
ベースURL解決new URL(relative, base)ブラウザ、Node.js絶対URL相対URLの解決に向きます
ES Modulesimport.meta.urlNode.js、ブラウザモジュールURL__dirnameとは使い方が違います
ファイルURL変換fileURLToPath()Node.jsファイルパスnode:urlから読み込みます
エラー処理try...catch共通例外捕捉非同期処理では扱いが変わります
配列走査forEach()共通なし早期終了には向きません

使い分けると、URL由来のパス取得にはURL、OS上のファイルパスにはnode:path、ディレクトリ内の一覧にはnode:fsが対応します。イベントと連動してファイル名を扱う場合は、JavaScriptイベント徹底解説!30個の使い方と応用例も入力処理の整理に役立ちます。

ファイル名の取得方法

JavaScriptのコードを表示した画面

ファイル名だけを取り出す処理は、アップロードされたファイル名の保存、ログ出力、拡張子判定などに使われます。ただし、ユーザー入力由来のファイル名をそのまま保存パスに結合すると、意図しない階層を参照する危険があるため注意点として分離して考える必要があります。

JavaScriptで単純な文字列から末尾の名前を取り出すなら、split()で区切り、pop()で末尾を読む形がわかりやすいです。一方、Node.jsでOS差異を含めて処理するなら、path.basename()を使うほうが意図を表しやすくなるのが目安です。

その使い方を学ぶときは、区切り文字に/だけを想定しないことが大切になります。Windowsパスにはが含まれるため、文字列処理だけで対応するなら正規表現/[\/]/で両方を扱う設計が現実的です。

サンプルコード1:ファイル名を取得する

フルパスからファイル名を取り出すには、区切り文字で配列に分けたうえで末尾要素を取得します。この方法はブラウザでもNode.jsでも動く文字列処理ですが、OSが解釈する実在パスかどうかまでは判定しません。

function getFileName(path) {
  return path.split(/[\/]/).pop();
}

const filePath = "/path/to/file.txt";
const fileName = getFileName(filePath);
console.log(fileName);

結果: 期待される出力はfile.txtです。/path/to/の部分は取り除かれ、末尾の名前だけが残りますし、これが一つの目安です。

サンプルコード2:ファイル拡張子を取得する

拡張子を取得する使い方では、ファイル名を.で分割して末尾を読む方法があります。ただし、archive.tar.gzのようにドットが複数あるファイルでは、最後のgzだけを拡張子として扱う点を理解しておくとよいです。

function getFileExtension(fileName) {
  return fileName.split('.').pop();
}

const fileName = "file.txt";
const fileExtension = getFileExtension(fileName);
console.log(fileExtension);

結果: 期待される出力はtxtです。ドットを含めた.txtが必要な場合は、Node.jsのpath.extname()も候補になります。

サンプルコード3:ファイル名から拡張子を取り除く

拡張子なしのベース名が必要な場面では、末尾の要素を除外してから再結合します。このときslice(0, -1)は最後の要素を落とした配列を返し、join('.')が残りの名前をつなぎ直するのがポイントです。

function removeFileExtension(fileName) {
  return fileName.split('.').slice(0, -1).join('.');
}

const fileName = "file.txt";
const fileNameWithoutExtension = removeFileExtension(fileName);
console.log(fileNameWithoutExtension);

結果: 期待される出力はfileです。file.txtから最後の拡張子部分だけが除かれます。

ただし、.envのようなドットで始まるファイル、拡張子がないREADME、末尾がドットのfile.は扱いが変わります。こうした注意点があるため、入力値の形式を決められる場合は、許可する拡張子をArraySetで管理すると判定が安定するのが一般的です。

一方、拡張子に関する処理を深く扱う場合は、JavaScriptで拡張子を活用する方法12選!初心者でも簡単にできる方法を紹介で入力チェックや拡張子別の分岐をあわせて確認できます。ファイル名のパス取得が整理できると、親ディレクトリを求める処理にも自然につながります。

ディレクトリ名の取得方法

ディレクトリ名の取得は、ファイルを保存する場所を決める処理や、関連ファイルを同じ階層から探す処理で使われますが、覚えておくと役立つでしょう。JavaScriptでは実行環境によって使えるAPIが変わるため、Node.jsの__dirnameとブラウザのlocation.pathnameを混ぜないことが出発点になります。

基本的に、__dirnameはCommonJSのモジュール内で利用される値です。ES Modulesではそのまま使えないため、import.meta.urlfileURLToPath()を組み合わせる使い方が必要になる場合があります。

そのため、学習用のサンプルでは__dirnameを見かけても、実際のプロジェクトがtype: "module"かどうかを確認するのが現実的です。Node.jsのモジュール仕様はNode.js Modules APIで確認できます。

サンプルコード4:現在のディレクトリ名を取得

CommonJS形式のNode.jsファイルでは、現在のスクリプトが置かれているディレクトリを__dirnameで参照できます。これはブラウザのJavaScriptには存在しない値なので、フロントエンドのコードに貼り付けても動きません。

const currentDir = __dirname;
console.log(currentDir);

結果: 期待される出力は、実行中のファイルが置かれているディレクトリの絶対パスです。例として/home/app/srcのような形式になると整理できます。

ただし、ES Modulesで同じことを行う場合はimport.meta.urlfileURLToPath()に渡してファイルパスへ変換します。CommonJSとES Modulesの違いを意識しておくことは、パス取得の注意点として特に押さえたい部分です。

サンプルコード5:指定したパスのディレクトリ名を取得

指定したファイルパスから親ディレクトリを取り出すには、Node.jsのpath.dirname()を使います。文字列を手で分割するより、OSのパス規則を踏まえた処理になり、Windows形式の扱いも読み取りやすくなると理解できます。

const path = require('path');

const filePath = "/path/to/file.txt";
const dirName = path.dirname(filePath);
console.log(dirName);

結果: 期待される出力は/path/toです。末尾のfile.txtを除いた親ディレクトリが得られます。

一方、ブラウザではローカルファイルシステムの任意パスを取得できません。これはセキュリティ上の制約であり、ユーザーが選択したファイルでもinput type="file"から得られるのは通常File.nameなどの限定情報になります。

具体的には、WebページのURL上のディレクトリだけが必要ならlocation.pathnameを分割すると覚えるとよいでしょう。実際のサーバー上のディレクトリ構造とは一致しない場合もあるため、URLのパス取得とサーバー内部のファイルパス取得は別物として整理します。

相対パスと絶対パスの取得

相対パスと絶対パスは、基準位置の有無で意味が変わります。相対パスは./file.txt../file.txtのように現在位置からの関係を示し、絶対パスは/path/to/file.txtC:pathtofile.txtのようにルートやドライブからの位置を示すると考えられます。

そのため、JavaScriptで相対パスを扱うときは、どのディレクトリを基準に解決するのかを明確にします。Node.jsのprocess.cwd()はコマンドを実行した作業ディレクトリを返し、__dirnameはファイルが置かれたディレクトリを返すため、似ていても用途が違います。

ブラウザの場合、相対URLは現在のページURLや<base>要素の影響を受けますし、ここを基本と考えるとよいでしょう。MDNのURL APIにあるように、new URL(relative, base)を使うと基準URLに対して安全に解決できます。

⚠️ 注意: OSのファイルパスとURLのパスは同じ文字列に見えても規則が異なります。URLでは区切り文字に/を使い、WindowsのをURL区切りとして扱わないようにすると言えるでしょう。

相対パスと絶対パスの違い

相対パスは、コードを移動したときに基準位置も変わる可能性があります。たとえば./assets/logo.pngは現在位置のassetsを指しますが、実行場所やビルド設定が変わると別の場所を参照するかもしれません。

一方、絶対パスは基準が固定されるため、ファイルシステム上の位置を明示しやすくなります。ただし、開発環境の/Users/name/projectC:Usersnameprojectをそのまま本番環境へ持ち込むと動かないため、環境変数や設定値で切り替える設計が扱いやすくなるのが基本です。

使い分けると、アプリケーション内部で固定の保存先を扱う処理には絶対パス、HTMLやCSSから画像を参照する処理には相対URLが合う場合があります。JavaScriptのビルドツールを使う構成では、importpublicディレクトリの規則も確認します。

サンプルコード6:相対パスを取得する

相対パスそのものは、単なる文字列として変数に保持できるのが目安です。この段階ではファイルの存在確認は行われず、後続の読み込み処理やURL解決処理で初めて意味を持ちます。

const relativePathToFile = "./file.txt";
console.log(relativePathToFile);

const relativePathToParentFile = "../file.txt";
console.log(relativePathToParentFile);

結果: 期待される出力は./file.txt../file.txtです。文字列を表示しているだけなので、ファイルが存在するかどうかは判定されません。

サンプルコード7:絶対パスを取得する

Node.jsで絶対パスを作るには、path.resolve()を使います。引数がすでに絶対パスの場合は正規化された形になり、相対パスの場合は現在の作業ディレクトリを基準に解決されます。

const path = require('path');

const absolutePath = path.resolve("/path/to/file.txt");
console.log(absolutePath);

結果: 期待される出力は/path/to/file.txtのような絶対パスです。OSや入力値によって区切り文字の表記は変わりますし、ここがポイントです。

サンプルコード8:相対パスを絶対パスに変換する

相対パスを絶対パスへ変換する場合も、path.resolve()を使います。このとき基準になるのは、通常process.cwd()が返す作業ディレクトリです。

const path = require('path');

const relativePath = "./file.txt";
const absolutePath = path.resolve(relativePath);
console.log(absolutePath);

結果: 期待される出力は、現在の作業ディレクトリにfile.txtを結合した絶対パスです。例として/home/app/file.txtのような形式になります。

このときの注意点は、スクリプトの場所とコマンド実行場所が一致するとは限らないことです。CLIツールやテストコードでは、process.cwd()__dirnameの差が原因でファイルが見つからないケースがあるのがポイントです。

対処法として、設定ファイルの場所を基準にする、path.join(__dirname, 'file.txt')のようにファイル基準で組み立てる、または起動時に基準ディレクトリを明示する方法があります。配列処理を組み合わせるなら、JavaScriptのforEachでreturnを活用する6つのテクニックもディレクトリ走査の理解に役立ちます。

ディレクトリ内のファイル一覧取得

ディレクトリ内のファイル一覧取得は、Node.jsの役割になるのが一般的です。ブラウザのJavaScriptはセキュリティ上、ユーザーの端末内にある任意ディレクトリを自由に列挙できないため、fs.readdir()のようなファイルシステムAPIは使えません。

Node.jsではnode:fsモジュールを使い、指定したディレクトリ内の名前を配列として受け取ります。公式ドキュメントのNode.js File system APIでは、コールバック版、Promise版、同期版の使い方が整理されています。

ただし、一覧取得で返るのは名前の配列であり、ファイルかディレクトリかの判定は別途必要です。withFileTypesオプションを使うか、fs.stat()で状態を調べることで、通常ファイル、ディレクトリ、シンボリックリンクを分けられますが、これは押さえたい点です。

💡 Tips: 新しいコードではfs.promises.readdir()awaitを使うと、ネストが深いコールバックを避けやすくなります。既存コードがコールバック版なら、エラー引数errの処理を必ず残します。

Node.jsでのファイル一覧取得

Node.jsのfs.readdir()は、指定したディレクトリに含まれるエントリ名を読み取りますし、これが一つの目安です。ファイル一覧のパス取得まで行いたい場合は、返ってきた名前にpath.join()で親ディレクトリを結合します。

一般に、一覧取得ではエラー処理を省かない構成にします。存在しないディレクトリならENOENT、権限不足ならEACCESが発生するため、対処法をコード内に用意しておくと原因を追いやすくなるのが現実的です。

サンプルコード9:ディレクトリ内のファイル一覧を取得

コールバック版のfs.readdir()は、エラーとファイル名配列を受け取ります。errがある場合は処理を止め、成功時だけfilesを扱う流れにします。

const fs = require('fs');

fs.readdir('/path/to/directory', (err, files) => {
  if (err) {
    console.error('Error reading directory:', err.message);
    return;
  }

  console.log('Files in directory:', files);
});

結果: 期待される出力はFiles in directory: [...]の形式です。対象ディレクトリが存在しない場合は、エラーメッセージが表示される想定になると整理できます。

このコードの注意点は、/path/to/directoryを実在するディレクトリへ置き換える必要があることです。サンプル用の仮パスをそのまま使うと、ENOENTが返る可能性があります。

サンプルコード10:再帰的にサブディレクトリのファイル一覧を取得

サブディレクトリの中まで調べる場合は、ディレクトリを見つけるたびに同じ関数を呼び出します。同期版は流れを追いやすい一方で、対象数が多いと処理が止まる時間が長くなるため、用途を限定して使いると理解できます。

const fs = require('fs');
const path = require('path');

function getFilesRecursive(dirPath, arrayOfFiles) {
  const files = fs.readdirSync(dirPath);
  arrayOfFiles = arrayOfFiles || [];

  files.forEach((file) => {
    const fullPath = path.join(dirPath, file);

    if (fs.statSync(fullPath).isDirectory()) {
      arrayOfFiles = getFilesRecursive(fullPath, arrayOfFiles);
    } else {
      arrayOfFiles.push(fullPath);
    }
  });

  return arrayOfFiles;
}

const files = getFilesRecursive('/path/to/directory');
console.log('Files in directory (recursive):', files);

結果: 期待される出力は、サブディレクトリ内のファイルパスを含む配列です。対象パスや権限によってはENOENTEACCESが発生する可能性があります。

この再帰処理ではforEach()を使っていますが、途中で探索を止めたい場合はfor...ofのほうが扱いやすくなります。forEach()map()の違いを整理するなら、【保存版】JavaScriptエンジニア必見!forEach・mapの"目からウロコ"な使い分け術10選も参考になると覚えるとよいでしょう。

実際の開発では、シンボリックリンクの循環、巨大なディレクトリ、アクセス権のないフォルダも考慮します。こうした注意点を無視すると、パス取得そのものよりも探索処理の停止条件で問題が起きやすくなります。

URLからのパス取得

URLからのパス取得は、ブラウザで現在ページを判定したり、ルーティング処理で画面を切り替えたり、クエリ文字列を除いたパスだけを扱ったりする場面で使いると考えられます。JavaScriptのURL処理では、window.locationURLオブジェクトを使い分けると読みやすくなります。

その中でも、現在開いているページに関する情報はwindow.locationから取得します。MDNのWindow.locationでは、hrefpathnamesearchhashなどのプロパティが整理されていると言えるでしょう。

一方、任意のURL文字列を解析する場合はnew URL()が適しています。文字列分割だけでURLを扱うと、クエリ、ハッシュ、末尾スラッシュ、URLエンコードを見落としやすいため、標準APIに任せるほうが堅実です。

サンプルコード11:現在のページのURLを取得

現在ページの完全なURLが必要な場合は、window.location.hrefを読み取ります。完全なURLにはプロトコル、ホスト、パス、クエリ、ハッシュが含まれる場合があるのが基本です。

const currentURL = window.location.href;
console.log('Current URL:', currentURL);

結果: 期待される出力はCurrent URL: https://example.com/path/to/page.htmlのような形式です。実際の値は閲覧中のページURLによって変わります。

サンプルコード12:URLからファイル名を取得

URLのパス部分だけを使う場合は、window.location.pathnameを読み取ります。その値を/で分割し、末尾をpop()で取り出すとファイル名に相当する部分が得られますが、覚えておくと役立つでしょう。

const pathname = window.location.pathname;
const fileName = pathname.split('/').pop();
console.log('File name:', fileName);

結果: 期待される出力はFile name: file.htmlのような形式です。URLがhttps://example.com/path/to/file.htmlなら、末尾のfile.htmlが対象になります。

ただし、URLが/docs/のように末尾スラッシュで終わる場合、pop()の結果が空文字になる可能性があります。対処法として、分割前にreplace(//$/, '')で末尾スラッシュを取り除く、またはfilter(Boolean)で空要素を除く方法があるのが目安です。

サンプルコード13:URLからディレクトリパスを取得

URLのディレクトリ部分を取り出す場合は、パスを分割して末尾要素を除き、残りを/で結合します。ファイル名の抽出と同じ考え方ですが、残す範囲が逆になります。

const pathname = window.location.pathname;
const dirPath = pathname.split('/').slice(0, -1).join('/');
console.log('Directory path:', dirPath);

結果: 期待される出力はDirectory path: /path/toのような形式です。URLがhttps://example.com/path/to/file.htmlなら、ファイル名を除いたパスが残りますし、ここを基本と考えるとよいでしょう。

この使い方は、現在ページと同じ階層にある画像やJSONファイルのURLを作りたい場合に役立ちます。ただし、ルーティングを使うSPAではURL上のパスとサーバー上のファイル配置が一致しないため、相対URLの解決にはnew URL('data.json', location.href)のような形も検討します。

同様に、クリックやフォーム操作をきっかけにパス取得を行う場合は、イベントハンドラの書き方も結果に影響するのがポイントです。イベント登録の整理には、JavaScriptにおけるイベントハンドラを完全ガイド!20選の実践サンプルコード付きが補助になります。

よくあるエラーと対処法

JavaScriptのパス取得で起きるエラーは、環境の取り違え、区切り文字の違い、存在しないパス、権限不足に分類できます。エラー文にENOENTEACCESReferenceErrorTypeErrorが含まれる場合は、原因の方向性をかなり絞れますし、ここがポイントです。

初心者がつまずきやすいのは、ブラウザでNode.js専用APIを使うケースです。たとえばブラウザの開発者ツールでrequire('path')を実行すると、通常はrequireが定義されていないというエラーになります。

その対処法は、URL処理ならURLlocationへ置き換え、ファイルシステム処理ならサーバー側のNode.jsへ移すことです。Webアプリケーションでは、ブラウザがファイル名を送信し、サーバーが保存先パスを決める役割分担が一般的になります。

ℹ️ 補足: document.write()を使って結果を画面へ出す古いサンプルもありますが、通常のアプリケーションではconsole.log()、DOM更新、テンプレート描画を使うほうが扱いやすくなるのが一般的です。

パスの区切り文字の違いによるエラー

Windowsではファイルパスの区切りにが使われ、LinuxやmacOSでは/が使われます。この違いを固定文字列で処理すると、開発環境では動いても別OSで壊れることがあります。

対処法として、Node.jsではpath.join()path.resolve()path.normalize()を使い、手書きで"/"を連結しすぎないようにするのが現実的です。URLを作る場合はOSのpath.sepを使わず、URLの規則に従ってURLオブジェクトを使います。

具体的には、ファイルシステムのパス取得にはpath.join(baseDir, fileName)、URLのパス生成にはnew URL(fileName, baseUrl)を使い分けます。両者を混ぜると、Windows環境でURLにバックスラッシュが入るような不具合が起きやすくなると整理できます。

存在しないパスを指定した場合のエラー

存在しないファイルやディレクトリを読み込むと、Node.jsでは多くの場合ENOENTが発生します。これはパス文字列の組み立てが間違っている場合と、単純に対象ファイルがまだ作成されていない場合の両方で起こります。

その対処法として、処理前にfs.access()で確認する方法があると理解できます。ただし、確認後に別プロセスがファイルを削除する可能性もあるため、最終的な読み書き処理でもtry...catchやコールバックのerrを扱います。

一般に、ファイル作成を伴う処理では親ディレクトリの存在も確認します。fs.mkdir(){ recursive: true }を渡すと、必要な親ディレクトリをまとめて作成できるため、保存先のパス取得と組み合わせやすくなると覚えるとよいでしょう。

パーミッションエラー

読み取りや書き込みの権限がない場合は、EACCESEPERMが発生します。たとえばシステム領域へファイルを書き込もうとしたり、実行ユーザーに読み取り権限がないディレクトリを列挙したりすると、この種類のエラーが返ることがあります。

対処法として、保存先をアプリケーションが管理するディレクトリへ限定し、必要に応じて実行ユーザーの権限を見直すると考えられます。コード側ではfs.access(path, fs.constants.R_OK)fs.constants.W_OKで権限確認を行い、失敗時のメッセージを利用者向けに整えます。

ただし、権限エラーを避けるために過剰な権限を付与するのは避けます。パス取得の失敗を握りつぶすより、どのパスで何が失敗したのかをログに残し、画面には必要最小限の情報を返すほうが運用しやすくなると言えるでしょう。

これらの注意点を押さえると、JavaScriptのパス取得は単なる文字列処理ではなく、実行環境と権限を含む設計要素として扱えます。とくにファイルアップロードや静的ファイル生成では、入力された名前を検証し、保存先を固定し、例外処理を残す流れが基本になります。

まとめ

JavaScriptでパス取得を行う際は、ブラウザのURL処理とNode.jsのファイルパス処理を分けて考えると理解しやすくなるのが基本です。ブラウザではlocation.pathnamenew URL()、Node.jsではpath.basename()path.dirname()path.resolve()fs.readdir()を使います。

その使い方を整理すると、ファイル名の取得は末尾要素の抽出、ディレクトリ名の取得は親パスの抽出、相対パスと絶対パスの取得は基準位置の明確化が中心になります。URLからのパス取得では、クエリやハッシュを含むhrefと、パス部分だけのpathnameを混同しないことが大切になるのが目安です。

一方、Node.jsでディレクトリ内のファイル一覧を扱う場合は、fs.readdir()で名前を取得し、必要に応じてpath.join()fs.statSync()でフルパス化と種別判定を行います。再帰的な探索では、権限不足、存在しないパス、シンボリックリンクの循環といった注意点も残ります。

具体的な対処法として、OS差異にはnode:path、存在確認にはfs.access()、例外処理にはtry...catchやコールバックのerrを使いるのがポイントです。パス取得の結果をそのまま信頼せず、入力検証と保存先の制限を組み合わせることで、ファイル操作の意図が明確になります。

JavaScriptのパス取得は、ファイル名、ディレクトリ名、相対パス、絶対パス、URLパスを別々に覚えるより、対象と環境でAPIを選ぶ形にすると応用しやすくなります。サンプルコードを土台に、ブラウザ側とサーバー側の責務を分けて設計するのが扱いやすい進め方です。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。