Пути к файлам (модуль path)
Почему не стоит склеивать пути строками вручную и что предлагает модуль path.
Модуль path — встроенный модуль для построения и разбора путей к файлам с учётом особенностей операционной системы.
Проблема разных ОС
В Unix-системах (Linux, macOS) разделитель путей — прямой слеш /, а в Windows — обратный \. Если склеивать пути вручную через +, код сломается на другой ОС или из-за лишних/недостающих слешей. Модуль path решает это за вас.
path.join — безопасная склейка
Функция join соединяет части пути правильным разделителем и убирает дубли слешей:
const path = require("path");
const full = path.join("src", "utils", "helpers.js");
console.log(full); // на Unix: src/utils/helpers.js
// лишние слеши и .. обрабатываются корректно
console.log(path.join("a/", "/b", "../c")); // a/c
path.resolve — абсолютный путь
resolve строит абсолютный путь от текущей папки. Это надёжнее относительных путей, которые зависят от того, откуда запущена программа:
const path = require("path");
console.log(path.resolve("data", "file.txt"));
// напр. /Users/me/project/data/file.txt
Разбор пути
path умеет и разбирать путь на части:
| Функция | Что вернёт для /app/index.js |
path.basename | index.js — имя файла |
path.dirname | /app — папка |
path.extname | .js — расширение |
const path = require("path");
const p = "/app/src/index.js";
console.log(path.basename(p)); // index.js
console.log(path.dirname(p)); // /app/src
console.log(path.extname(p)); // .js
__dirname и __filename
В CommonJS-модулях доступны две полезные переменные: __dirname — путь к папке текущего файла, __filename — путь к самому файлу. С ними строят пути, не зависящие от места запуска:
const path = require("path");
// надёжный путь к файлу рядом с этим скриптом
const configPath = path.join(__dirname, "config.json");
console.log(configPath);
Это частый приём: path.join(__dirname, ...) всегда указывает относительно файла, а не относительно того, откуда запустили node. Разница важна: относительный путь "config.json" Node ищет от текущей рабочей директории — то есть от папки, в которой вы набрали команду. Запустите тот же скрипт из другого места — и относительный путь укажет не туда. А __dirname привязан к самому файлу и не зависит от места запуска. Поэтому для надёжного доступа к файлам рядом со скриптом всегда отталкивайтесь от __dirname.
В ES-модулях переменных __dirname и __filename нет — там путь к текущему файлу получают из import.meta.url. Но идея та же: строить пути относительно расположения файла, а не относительно места запуска.
Разбор расширения — это работа со строкой
Сам по себе разбор имени файла — обычный JavaScript. Вот упрощённый аналог extname:
function getExtension(fileName) {
const dot = fileName.lastIndexOf(".");
if (dot <= 0) return ""; // нет точки или скрытый файл
return fileName.slice(dot);
}
console.log(getExtension("photo.png"));
console.log(getExtension("archive.tar.gz"));
console.log(getExtension("README"));
Вывод:
.png .gz
Итог
- Не склеивайте пути вручную через
+— используйтеpath.join. path.resolveстроит абсолютный путь, более надёжный.basename,dirname,extnameразбирают путь на части.__dirname— папка текущего файла;path.join(__dirname, ...)— частый приём.