Модуль path: join, resolve, basename, dirname

Модуль 4: Node.js, Next.js и Angular
3 уровень , 6 лекция
Открыта

1. Для чего нужен модуль path?

Давайте начнём с вопроса: почему вообще нужен отдельный модуль для работы с путями? Почему нельзя просто писать './data/file.txt' или 'C:\\Users\\...'?

Дело в том, что разные операционные системы по-разному трактуют пути к файлам:

  • В Windows используется обратный слэш \ (например, C:\Users\Bob\file.txt).
  • В Linux и macOS — прямой слэш / (например, /home/bob/file.txt).

Если вы жёстко пропишете путь с неправильными слэшами, ваш код может не заработать на другой ОС. Кроме того, часто нужно склеить несколько частей пути, получить имя файла из полного пути, узнать родительскую папку — и всё это хочется делать без ручных манипуляций со строками.

Вот тут и приходит на помощь стандартный модуль Node.js — path. Он делает работу с путями универсальной, безопасной и удобной.

Подключение модуля path

Модуль path — это часть стандартной библиотеки Node.js, его не нужно устанавливать через npm. Просто подключаем:

const path = require('path');

Если вы используете ES-модули:

import path from 'path';

// В последних версиях Node.js некоторые методы доступны только через импорт с суффиксом .js, но для большинства задач подойдёт классический подход.

2. Склеивание путей: path.join()

Зачем нужен join?

Очень частая задача — склеить несколько частей пути в один корректный путь. Например, у вас есть директория и имя файла, и вы хотите получить полный путь к файлу.

Плохой способ:

const fullPath = 'data' + '/' + 'notes.txt'; // А если на Windows?

Хороший способ:

const path = require('path');
const fullPath = path.join('data', 'notes.txt');
console.log(fullPath); // 'data/notes.txt' (Linux/macOS) или 'data\notes.txt' (Windows)

Как работает join?

  • Склеивает все аргументы, аккуратно расставляя нужные разделители (/ или \).
  • Удаляет лишние разделители, если они есть.
  • Не обращает внимания на абсолютный путь в середине (он "обнуляет" всё, что было до него).

Примеры:

const p1 = path.join('folder', 'subfolder', 'file.txt');
// 'folder/subfolder/file.txt' (Linux/macOS)
// 'folder\subfolder\file.txt' (Windows)

const p2 = path.join('/home/user', 'docs', 'notes.txt');
// '/home/user/docs/notes.txt'

const p3 = path.join('C:\\Users', 'Alice', 'file.txt');
// 'C:\Users\Alice\file.txt'

Особенности:

Если один из аргументов — абсолютный путь, всё, что было до него, игнорируется:

console.log(path.join('/foo', 'bar', '/baz')); // '/baz'

Практика: используем в приложении

Допустим, у нас есть папка data, где мы храним заметки. В нашем мини-приложении мы хотим получить путь к файлу заметки:

const notesDir = 'data';
const noteFile = 'note1.txt';
const notePath = path.join(notesDir, noteFile);
console.log(notePath); // 'data/note1.txt' или 'data\note1.txt'

3. Получение абсолютного пути: path.resolve()

В чём разница между join и resolve?

  • path.join() — просто склеивает части пути.
  • path.resolve() — строит абсолютный путь, начиная с текущей директории (или с первой абсолютной части).

Как работает resolve?

  • Если ни одна часть не абсолютная, путь строится относительно текущей рабочей директории (process.cwd()).
  • Если встречается абсолютный путь, всё, что было до него, игнорируется, и путь строится от него.

Примеры:

console.log(path.resolve('data', 'notes.txt'));
// '/Users/you/project/data/notes.txt' (если вы в '/Users/you/project')

console.log(path.resolve('/tmp', 'file.txt'));
// '/tmp/file.txt'

Отличие:

console.log(path.join('foo', '/bar', 'baz'));
// '/bar/baz'

console.log(path.resolve('foo', '/bar', 'baz'));
// '/bar/baz'

Но если все части относительные:

console.log(path.join('foo', 'bar', 'baz'));
// 'foo/bar/baz'

console.log(path.resolve('foo', 'bar', 'baz'));
// '/текущий/путь/foo/bar/baz'

Практика: получаем абсолютный путь к файлу

const relativePath = path.join('data', 'note1.txt');
const absolutePath = path.resolve(relativePath);
console.log(absolutePath);
// Например: '/Users/you/project/data/note1.txt'

4. Имя файла и родительская директория: basename и dirname

path.basename()

Получает имя файла из полного пути.

const filePath = '/home/user/docs/notes.txt';
console.log(path.basename(filePath)); // 'notes.txt'

Можно указать расширение, чтобы его убрать из результата:

console.log(path.basename(filePath, '.txt')); // 'notes'

path.dirname()

Возвращает путь к родительской директории:

const filePath = '/home/user/docs/notes.txt';
console.log(path.dirname(filePath)); // '/home/user/docs'

Практика: выводим имя файла и папку

const notePath = path.join('data', 'note1.txt');
console.log('Имя файла:', path.basename(notePath));
console.log('Папка:', path.dirname(notePath));

5. Пример: собираем всё вместе

Давайте добавим в наше мини-приложение функцию, которая принимает имя файла заметки и выводит:

  • Абсолютный путь к заметке
  • Имя файла
  • Папку, где лежит файл
const path = require('path');

function printNotePath(noteFileName) {
  const notesDir = 'data';
  const notePath = path.join(notesDir, noteFileName);
  const absolutePath = path.resolve(notePath);
  const fileName = path.basename(notePath);
  const parentDir = path.dirname(notePath);

  console.log('Относительный путь:', notePath);
  console.log('Абсолютный путь:', absolutePath);
  console.log('Имя файла:', fileName);
  console.log('Папка:', parentDir);
}

printNotePath('note1.txt');

Результат:

Относительный путь: data/note1.txt
Абсолютный путь: /Users/you/project/data/note1.txt
Имя файла: note1.txt
Папка: data

6. Дополнительные полезные методы модуля path

path.extname()

Возвращает расширение файла (с точкой):

console.log(path.extname('data/note1.txt')); // '.txt'
console.log(path.extname('archive.tar.gz')); // '.gz'

path.sep и path.delimiter

  • path.sep — разделитель путей для вашей ОС (/ или \)
  • path.delimiter — разделитель переменных окружения (: или ;)
console.log('Разделитель:', path.sep); // '/' или '\'

Схема: основные методы модуля path


         +---------------------+
         |    path.join()      |  <-- Склеивает части пути
         +---------------------+
                   |
                   v
         +---------------------+
         |  path.resolve()     |  <-- Получает абсолютный путь
         +---------------------+
                   |
                   v
         +---------------------+
         |  path.basename()    |  <-- Имя файла
         +---------------------+
                   |
                   v
         +---------------------+
         |  path.dirname()     |  <-- Родительская папка
         +---------------------+

7. Типичные ошибки при работе с path

Ошибка №1: Ручное склеивание путей через + или шаблонные строки.
Это работает только до первой попытки запустить код на другой операционной системе. Никогда не пишите 'data/' + fileName — используйте path.join().

Ошибка №2: Путают join и resolve.
join просто склеивает части, не делая абсолютным путь, а resolve всегда возвращает абсолютный путь. Если вы хотите получить путь, который точно работает из любого места проекта — используйте resolve.

Ошибка №3: Не учитывают абсолютные пути в середине join/resolve.
Если один из аргументов — абсолютный путь, всё, что было до него, игнорируется. Это может привести к неожиданным результатам.

Ошибка №4: Используют __dirname без path.
Если вы пишете __dirname + '/data/file.txt', на Windows получите ошибку. Всегда используйте path.join(__dirname, 'data', 'file.txt').

Ошибка №5: Не используют расширение файла в basename/extname.
Если забыть указать расширение в basename(file, ext), результат будет неожиданным. Проверяйте расширения файлов заранее.

1
Задача
Модуль 4: Node.js, Next.js и Angular, 3 уровень, 6 лекция
Недоступна
Получение абсолютного пути
Получение абсолютного пути
1
Задача
Модуль 4: Node.js, Next.js и Angular, 3 уровень, 6 лекция
Недоступна
Получение имени файла и директории из полного пути
Получение имени файла и директории из полного пути
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ