При наличии нескольких точек входа в Webpack часто возникает ситуация, когда разные части приложения используют одни и те же библиотеки, модули или утилиты. Без дополнительной настройки такие зависимости дублируются в каждом бандле, что приводит к увеличению общего размера сборки, лишним загрузкам и снижению производительности. Управление общими зависимостями становится ключевым элементом оптимизации многобандловых приложений.
При конфигурации Webpack с несколькими точками входа формируется отдельный граф зависимостей для каждой из них. Например:
appadminЕсли оба модуля используют lodash, moment
или общий внутренний модуль, Webpack по умолчанию включает эти
зависимости в каждый итоговый бандл.
Это поведение объясняется тем, что Webpack рассматривает каждый entry как независимый контекст сборки. Отсутствует автоматическое понимание того, что некоторые модули могут быть извлечены в общий слой.
В результате формируется избыточная структура:
Повторяющийся код увеличивает размер загрузки и ухудшает кэширование.
Разделение общих зависимостей позволяет:
Особенно заметен эффект в приложениях с административными панелями, пользовательскими интерфейсами и отдельными лендингами, где используется общий набор утилит и UI-компонентов.
Основной механизм устранения дублирования в Webpack —
SplitChunksPlugin, встроенный в систему оптимизации.
Базовая конфигурация:
module.exports = {
entry: {
app: './src/app.js',
admin: './src/admin.js'
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
При таком режиме Webpack анализирует все зависимости и автоматически выделяет общие модули в отдельные чанки.
Алгоритм разделения включает несколько этапов:
По умолчанию учитываются параметры:
Webpack стремится найти баланс между количеством файлов и степенью повторного использования.
cacheGroups позволяют управлять стратегией извлечения
общих модулей.
Пример настройки:
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
Здесь все зависимости из node_modules выносятся в
отдельный файл vendors.
Это приводит к следующей структуре:
Помимо внешних библиотек, часто требуется выделить общие внутренние модули проекта.
Пример:
cacheGroups: {
common: {
test: /[\\/]src[\\/]shared[\\/]/,
name: 'common',
minChunks: 2,
chunks: 'all'
}
}
Параметр minChunks: 2 означает, что модуль должен
использоваться минимум в двух точках входа, чтобы попасть в общий
бандл.
Это позволяет:
Webpack предоставляет несколько параметров для тонкой настройки:
minSize: 20000
Модуль будет вынесен в отдельный chunk только если его размер превышает заданный порог.
maxSize: 50000
Позволяет дробить крупные чанки на более мелкие.
Определяет количество повторных использований модуля.
minChunks: 2
Используется для контроля уровня «общности» кода.
Позволяет задавать приоритет cacheGroup:
priority: 10
Если модуль подходит под несколько групп, выбирается группа с более высоким приоритетом.
Параметр chunks определяет область анализа:
initial — только синхронные зависимости entry
pointsasync — только динамически загружаемые модулиall — объединённый анализНаиболее эффективным для общего кода считается режим
all, так как он позволяет находить пересечения между всеми
типами загрузки.
Выделение общих зависимостей существенно улучшает работу кэша браузера.
Если библиотека вынесена в отдельный файл:
Это особенно важно при использовании долгоживущих кэшей с
contenthash.
Пример:
Часто встречаются следующие проблемы:
При слишком маленьком minSize создаётся большое
количество файлов, что увеличивает накладные расходы на загрузку.
Отсутствие выделения node_modules приводит к повторной
загрузке тяжёлых библиотек.
Слишком высокое значение приводит к тому, что общие модули не выделяются вовсе.
При одинаковом приоритете нескольких групп Webpack может распределять модули неочевидным образом.
В многоточечных приложениях обычно применяется комбинация:
Пример:
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 20
},
common: {
test: /[\\/]src[\\/]shared[\\/]/,
name: 'common',
minChunks: 2,
priority: 10
}
}
}
}
Такая структура обеспечивает предсказуемое разделение и стабильное кэширование.
При использовании import() Webpack автоматически создаёт
отдельные чанки для асинхронных модулей. Если такие модули содержат
общие зависимости, они могут быть дополнительно вынесены в shared
chunks.
Это позволяет:
Разделение общих зависимостей тесно связано с tree shaking:
Эти механизмы работают на разных уровнях, но дополняют друг друга, обеспечивая минимальный итоговый размер сборки.
В приложениях с несколькими точками входа типичная картина без оптимизации:
После настройки общих зависимостей: