CopyWebpackPlugin: копирование статических файлов

CopyWebpackPlugin предназначен для переноса файлов и каталогов из исходных директорий проекта в итоговую сборку Webpack без их трансформации. Плагин работает на уровне ассетов сборки и выполняет копирование до финальной эмиссии файлов, обеспечивая перенос изображений, шрифтов, JSON, статических HTML-фрагментов и любых других ресурсов, не требующих обработки загрузчиками.

Место в архитектуре сборки Webpack

В системе Webpack обработка ресурсов делится на два основных механизма:

  • loaders — трансформация модулей (JS, CSS, изображения как модули)
  • plugins — расширение поведения сборщика

CopyWebpackPlugin относится ко второй категории и действует на этапе генерации ассетов, когда граф модулей уже построен.

Основная задача плагина:

  • перенос файлов, не входящих в dependency graph Webpack
  • сохранение структуры каталогов
  • подготовка статических ресурсов для production-сборки

Установка и подключение

npm install copy-webpack-plugin --save-dev

Подключение в конфигурации Webpack:

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  plugins: [
    new CopyWebpackPlugin({
      patterns: []
    })
  ]
};

Базовая структура конфигурации

Конфигурация плагина строится вокруг массива patterns, где каждый элемент описывает правило копирования.

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'public',
      to: 'dist'
    }
  ]
});

Параметры pattern

  • from — источник (файл или директория)
  • to — путь назначения
  • context — базовая директория для относительных путей
  • globOptions — настройки поиска файлов
  • filter — функция фильтрации
  • noErrorOnMissing — игнорировать отсутствие файлов

Копирование директорий

Типовой сценарий — перенос папки public в выходной каталог сборки:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'public',
      to: ''
    }
  ]
});

Поведение:

  • сохраняется структура директорий
  • файлы копируются без изменений
  • поддерживаются вложенные каталоги

Использование glob-паттернов

Плагин поддерживает glob-выражения через globOptions.

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'assets/**/*',
      globOptions: {
        ignore: ['**/*.psd']
      }
    }
  ]
});

Основные возможности:

  • **/* — рекурсивное копирование
  • * — файлы одного уровня
  • ignore — исключение файлов

Фильтрация файлов

Функция filter позволяет динамически исключать файлы:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'assets',
      filter: (resourcePath) => {
        return !resourcePath.endsWith('.map');
      }
    }
  ]
});

Механика:

  • вызывается для каждого файла
  • возвращает true или false
  • позволяет реализовать кастомные правила включения

Изменение структуры выходных файлов

Параметр to поддерживает функции для динамического формирования пути:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'images',
      to: ({ context, absoluteFilename }) => {
        return 'static/images/' + absoluteFilename.split('/').pop();
      }
    }
  ]
});

Возможности:

  • переименование файлов
  • flatten структуры
  • группировка ресурсов

Контекст копирования

context определяет базовую папку для относительных путей:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'src/assets',
      context: 'src',
      to: 'assets'
    }
  ]
});

Поведение:

  • пути рассчитываются относительно context
  • упрощается контроль структуры output

Игнорирование отсутствующих файлов

Опция noErrorOnMissing предотвращает падение сборки:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'optional-assets',
      noErrorOnMissing: true
    }
  ]
});

Используется при:

  • условных директориях
  • модульных конфигурациях
  • монорепозиториях

Копирование отдельных файлов

Плагин работает не только с директориями:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'config/config.json',
      to: 'config.json'
    }
  ]
});

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

  • сохраняется содержимое без изменений
  • можно переименовывать при копировании

Интеграция с HTML-сборкой

Часто используется совместно с HTML-генерацией, где статические файлы должны присутствовать в output:

  • favicon
  • robots.txt
  • manifest.json
  • статические изображения

Пример:

new CopyWebpackPlugin({
  patterns: [
    { from: 'public/favicon.ico' },
    { from: 'public/robots.txt' },
    { from: 'public/manifest.json' }
  ]
});

Игнорирование и оптимизация сборки

Ключевые механизмы оптимизации:

  • исключение ненужных файлов через ignore
  • фильтрация через filter
  • минимизация количества паттернов
  • использование точечных путей вместо глобальных масок

Пример оптимизированной конфигурации:

new CopyWebpackPlugin({
  patterns: [
    {
      from: 'assets',
      globOptions: {
        ignore: ['**/*.md', '**/*.psd', '**/raw/**']
      }
    }
  ]
});

Работа с производственной сборкой

В production-режиме CopyWebpackPlugin часто выполняет роль финального шага подготовки:

  • перенос уже оптимизированных ресурсов
  • добавление статических файлов окружения
  • формирование структуры dist

При этом важно учитывать:

  • отсутствие трансформации файлов
  • необходимость предварительной оптимизации изображений через loader или отдельные плагины

Отличие от file-loader и asset modules

CopyWebpackPlugin не заменяет загрузчики:

  • loaders включают ресурсы в dependency graph
  • CopyWebpackPlugin работает вне графа

Сравнение:

  • file-loader: импорт внутри JS
  • asset modules: встроенная обработка ресурсов
  • CopyWebpackPlugin: прямое копирование файловой системы

Использование в монорепозиториях

В монорепозиториях плагин применяется для:

  • копирования shared-asset пакетов
  • переноса статических ресурсов между приложениями
  • унификации структуры dist

Пример:

new CopyWebpackPlugin({
  patterns: [
    {
      from: '../. ./shared/assets',
      to: 'assets'
    }
  ]
});

Ограничения и особенности поведения

  • не обрабатывает содержимое файлов
  • не участвует в tree-shaking
  • не анализирует зависимости
  • выполняет только файловые операции
  • чувствителен к путям и context

Частые сценарии использования

  • перенос public директории
  • копирование шрифтов
  • перенос JSON-конфигураций
  • добавление статических HTML-файлов
  • подготовка PWA-ресурсов (manifest, icons)
  • доставка изображений без обработки loader’ами

Поведение при пересборке

В режиме watch:

  • копирование повторяется при изменении источника
  • пересчитываются только изменённые файлы
  • используется кэширование для ускорения операций

При incremental build:

  • повторное копирование минимизируется
  • исключаются неизменённые файлы

Совместимость с Webpack 5

В Webpack 5 плагин работает через modern hooks compilation API:

  • поддержка asset modules
  • улучшенная производительность
  • более точная работа с контекстами
  • обновлённая система glob

Структура конфигурации остаётся прежней, но внутренняя реализация оптимизирована под новую архитектуру сборщика.