Как скопировать папку с вложенными файлами и папками с помощью node:fs?nodejs-66

Для рекурсивного копирования папок с содержимым в Node.js можно использовать модуль fs (File System). Начиная с Node.js 16.7.0, появилась удобная функция fs.cp(), но я также покажу альтернативные подходы.

1. Использование fs.cp

const fs = require('fs/promises');

async function copyDirectory(src, dest) {
  try {
    await fs.cp(src, dest, { recursive: true });
    console.log('Directory copied successfully');
  } catch (err) {
    console.error('Error copying directory:', err);
  }
}

// Использование
copyDirectory('./source', './destination');

Параметры:

  • src: исходный путь
  • dest: путь назначения
  • options: { recursive: true } - копирует рекурсивно

2. Альтернативный способ с fs-extra

Если вы используете более старую версию Node.js, можно установить популярный пакет fs-extra:

npm install fs-extra
const fse = require('fs-extra');

async function copyDirectory(src, dest) {
  try {
    await fse.copy(src, dest);
    console.log('Directory copied successfully');
  } catch (err) {
    console.error('Error copying directory:', err);
  }
}

copyDirectory('./source', './destination');

3. Ручная реализация с fs и path

Для понимания внутренней работы можно реализовать копирование вручную:

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

function copyDirSync(src, dest) {
  // Создаем целевую директорию, если ее нет
  if (!fs.existsSync(dest)) {
    fs.mkdirSync(dest, { recursive: true });
  }

  // Читаем содержимое исходной директории
  const entries = fs.readdirSync(src, { withFileTypes: true });

  for (const entry of entries) {
    const srcPath = path.join(src, entry.name);
    const destPath = path.join(dest, entry.name);

    if (entry.isDirectory()) {
      // Рекурсивно копируем поддиректории
      copyDirSync(srcPath, destPath);
    } else {
      // Копируем файлы
      fs.copyFileSync(srcPath, destPath);
    }
  }
}

// Использование
copyDirSync('./source', './destination');

Важные замечания

  1. Асинхронность: Для production-кода лучше использовать асинхронные методы (fs.promises или fs-extra)
  2. Обработка ошибок: Всегда обрабатывайте возможные ошибки (EACCES, ENOENT и др.)
  3. Симлинки: В примерах выше симлинки копируются как файлы. Если нужно сохранить их природу, потребуется дополнительная обработка
  4. Производительность: Для больших директорий рассмотрите потоковое копирование

Резюмируем

Для современных проектов используйте fs.cp() с опцией recursive: true. Для legacy-проектов - fs-extra. Ручная реализация полезна для обучения, но в production лучше использовать проверенные решения.

Если вам нужна максимальная производительность и контроль, рассмотрите использование потоков (Streams API) для копирования файлов.