Группы кэширования (cacheGroups): настройка стратегий

cacheGroups в Webpack представляют собой центральный механизм управления разбиением кода и кэшированием модулей в рамках SplitChunksPlugin. Именно через них задаются правила, по которым Webpack выделяет общие зависимости, сторонние библиотеки, повторно используемые фрагменты и формирует отдельные чанки, оптимизированные под долгосрочное хранение в кэше браузера.

cacheGroups работают как набор независимых правил, каждое из которых описывает стратегию извлечения модулей из основного графа зависимостей. Эти правила могут конкурировать между собой, иметь приоритеты, накладывать ограничения по размеру, количеству использований модуля и типу источника. В результате формируется гибкая система, позволяющая управлять структурой итогового бандла на уровне логики приложения и внешних зависимостей.

cacheGroups задаётся внутри конфигурации optimization.splitChunks:

module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        },
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        }
      }
    }
  }
};

Каждая группа представляет собой объект с набором параметров. Webpack анализирует каждый модуль и проверяет, подходит ли он под условия хотя бы одной группы. Если подходит сразу под несколько — применяется логика приоритетов.

Принцип работы механизма выбора групп

Процесс выбора cacheGroup происходит после построения графа зависимостей:

  1. Webpack анализирует модуль и его связи.
  2. Проверяет соответствие условиям cacheGroups.
  3. Определяет все подходящие группы.
  4. Выбирает группу с наивысшим priority.
  5. Помещает модуль в соответствующий чанк или создает новый.

Если приоритеты равны, применяется внутренняя эвристика: учитывается размер модуля, количество использований и текущая структура чанков.

Ключевые параметры cacheGroups

test

Параметр test определяет, какие модули попадают в группу. Это может быть регулярное выражение, функция или строка.

vendors: {
  test: /node_modules/
}

test является основным фильтром и часто используется для выделения сторонних библиотек.

priority

priority управляет порядком применения групп. Чем выше значение, тем раньше применяется правило.

highPriority: {
  test: /react/,
  priority: 20
}

При конфликте нескольких групп именно priority определяет итоговое решение.

minChunks

minChunks задаёт минимальное количество модулей, в которых должен использоваться файл, чтобы он был вынесен в отдельный чанк.

common: {
  minChunks: 3
}

Это позволяет выделять действительно общие зависимости, избегая преждевременного дробления кода.

minSize и maxSize

Эти параметры регулируют размер чанков:

small: {
  minSize: 20000,
  maxSize: 100000
}

minSize предотвращает создание слишком мелких чанков, а maxSize используется для дальнейшего дробления крупных.

reuseExistingChunk

Параметр reuseExistingChunk позволяет переиспользовать уже созданный чанк, если он удовлетворяет условиям.

common: {
  reuseExistingChunk: true
}

Это снижает дублирование кода и улучшает эффективность кэширования.

Типовые стратегии cacheGroups

Выделение vendor-кода

Одна из самых распространённых стратегий — отделение сторонних библиотек:

vendors: {
  test: /[\\/]node_modules[\\/]/,
  name: 'vendors',
  chunks: 'all'
}

Такой подход позволяет изолировать зависимости от бизнес-логики и использовать долгосрочный кэш браузера для редко меняющихся библиотек.

Выделение общего кода приложения

common: {
  minChunks: 2,
  name: 'common',
  chunks: 'all'
}

Эта группа формирует чанк с повторно используемыми модулями внутри приложения.

Разделение по функциональным областям

auth: {
  test: /auth/,
  name: 'auth-module',
  priority: 10
},
dashboard: {
  test: /dashboard/,
  name: 'dashboard-module',
  priority: 10
}

Такой подход используется в крупных приложениях с модульной архитектурой, где важно разделение по доменным зонам.

Поведение chunks внутри cacheGroups

Параметр chunks определяет, какие типы чанков участвуют в обработке:

  • all — все чанки (initial + async)
  • async — только динамические import()
  • initial — только синхронные зависимости
vendors: {
  test: /node_modules/,
  chunks: 'all'
}

Выбор chunks напрямую влияет на стратегию загрузки и поведение ленивых модулей.

name и динамическое именование

Параметр name задаёт имя создаваемого чанка. Он может быть строкой или функцией:

vendors: {
  test: /node_modules/,
  name(module) {
    const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/);
    return `npm.${packageName[1].replace('@', '')}`;
  }
}

Динамическое именование используется для более точного контроля над кэшированием сторонних библиотек.

enforce: принудительное применение правил

Параметр enforce отключает влияние глобальных ограничений splitChunks, таких как minSize и maxSize.

largeLib: {
  test: /large-library/,
  enforce: true
}

Это полезно для критически важных библиотек, которые необходимо выделить независимо от размеров.

Взаимодействие cacheGroups между собой

cacheGroups не работают изолированно. Они формируют конкурирующую систему правил:

  • один модуль может подходить под несколько групп
  • итоговое решение зависит от priority
  • при равных приоритетах учитываются size и usage
  • reuseExistingChunk может переопределить создание нового чанка

Такая система позволяет строить сложные стратегии оптимизации без явного ручного распределения модулей.

Гибридные стратегии

В реальных проектах cacheGroups редко используются в чистом виде. Обычно применяется комбинация стратегий:

cacheGroups: {
  vendors: {
    test: /node_modules/,
    priority: 20
  },
  common: {
    minChunks: 2,
    priority: 10
  },
  ui: {
    test: /components/,
    priority: 5,
    reuseExistingChunk: true
  }
}

Подобная конфигурация формирует многоуровневую структуру кэширования: внешние зависимости, общие модули и UI-компоненты разделяются на разные чанки.

Ошибки проектирования cacheGroups

Неправильная настройка часто приводит к деградации производительности:

  • слишком много мелких чанков увеличивает накладные расходы на загрузку
  • отсутствие priority вызывает непредсказуемое распределение модулей
  • чрезмерное использование minChunks задерживает появление общих чанков
  • пересекающиеся test-условия создают дублирование кода

Оптимальная стратегия всегда зависит от структуры приложения, частоты обновления зависимостей и модели загрузки страниц.

Поведение при долгосрочном кэшировании

cacheGroups напрямую влияют на стабильность хэшей чанков. При правильной настройке:

  • vendor-чанки изменяются редко
  • бизнес-логика обновляется независимо
  • общие модули не пересобираются без необходимости

Это позволяет браузеру эффективно использовать кэш и снижает объём повторной загрузки при обновлениях приложения.