Разделение зависимостей между точками входа в Webpack напрямую связано с механизмом формирования общих чанков и управлением повторно используемым кодом. При наличии нескольких entry-поинтов неизбежно возникает ситуация, когда одни и те же модули импортируются в разных частях приложения. Без оптимизации это приводит к дублированию кода в результирующих бандлах, увеличению общего размера сборки и ухудшению кешируемости.
При классической конфигурации с несколькими точками входа Webpack строит отдельные графы зависимостей для каждого entry. Если оба графа содержат одинаковые импорты, например утилиты, библиотеки или shared-компоненты, то без дополнительных настроек эти зависимости будут включены в каждый бандл отдельно.
Типичный пример:
// entry-a.js
import { formatDate } from './utils/date';
import { apiRequest } from './utils/api';
console.log(formatDate(Date.now()));
apiRequest('/endpoint-a');
// entry-b.js
import { formatDate } from './utils/date';
import { apiRequest } from './utils/api';
console.log(formatDate(Date.now()));
apiRequest('/endpoint-b');
В данном случае модуль utils/date и
utils/api оказываются в двух независимых чанках. Это
приводит к:
Основным механизмом устранения дублирования является
optimization.splitChunks. Именно он отвечает за анализ
графа модулей и выделение общих зависимостей в отдельные чанки.
Базовая конфигурация:
module.exports = {
entry: {
pageA: './src/entry-a.js',
pageB: './src/entry-b.js'
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
Параметр chunks: 'all' включает анализ как синхронных,
так и асинхронных зависимостей. В результате Webpack автоматически
выделяет общий код в отдельный chunk, который подключается к обоим
entry.
Webpack использует внутренние эвристики для определения “общности” модуля:
После анализа формируется отдельный chunk, обычно именуемый
автоматически (например, vendors~pageA~pageB.js).
Если splitChunks не настроен, Webpack не гарантирует
извлечение общего кода. В этом случае каждая entry-секция становится
полностью независимой единицей сборки. Это поведение может быть
допустимо только для очень маленьких приложений или специальных случаев,
где изоляция важнее оптимизации.
Автоматическое разделение не всегда даёт оптимальный результат:
Для более точного контроля используется комбинация
cacheGroups и стратегий приоритизации.
Механизм cacheGroups позволяет задавать правила
группировки модулей:
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
shared: {
name: 'shared',
minChunks: 2,
priority: 10,
reuseExistingChunk: true
}
}
}
}
};
Здесь:
minChunks: 2 гарантирует, что модуль должен встречаться
минимум в двух местахreuseExistingChunk предотвращает дублирование уже
выделенных модулейpriority управляет конфликтами между группамиПараллельно с splitChunks Webpack предоставляет механизм
dependOn, который позволяет явно выразить зависимость одной
точки входа от другой. Это не автоматическая оптимизация, а
декларативное управление графом entry.
Пример:
module.exports = {
entry: {
shared: './src/shared.js',
pageA: {
import: './src/page-a.js',
dependOn: 'shared'
},
pageB: {
import: './src/page-b.js',
dependOn: 'shared'
}
}
};
В этом случае:
shared загружается один разpageA и pageB используют его как базовый
слойsharedНесмотря на схожую цель — устранение дублирования — механизмы принципиально различаются.
dependOn:
splitChunks:
На практике оба механизма могут использоваться совместно.
dependOn задаёт архитектурный каркас, а
splitChunks оптимизирует вторичные пересечения.
Пример комбинированной схемы:
module.exports = {
entry: {
vendor: './src/vendor.js',
appA: {
import: './src/app-a.js',
dependOn: 'vendor'
},
appB: {
import: './src/app-b.js',
dependOn: 'vendor'
}
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
В этой модели:
vendor содержит стабильные библиотекиsplitChunks дополнительно извлекает пересечения между
appA и appBПри использовании dependOn Webpack корректирует runtime
таким образом, чтобы:
Это особенно важно при наличии side effects в модулях, так как порядок загрузки становится детерминированным.
Одной из распространённых проблем является чрезмерное дробление
entry-поинтов. Когда разработчик выносит слишком много логики в
dependOn, структура сборки становится жёсткой и плохо
масштабируемой.
Другой частый случай — одновременное использование
dependOn и агрессивного splitChunks без
понимания приоритетов, что может приводить к неожиданному разбиению
кода.
Webpack всегда применяет следующий порядок логики:
Это означает, что dependOn формирует базовую структуру,
а splitChunks уже оптимизирует её поверх.
Наиболее устойчивый подход к многоточечной сборке заключается в следующей структуре:
Такая комбинация позволяет:
Механизмы dependOn и splitChunks в
совокупности формируют основу управления повторно используемым кодом в
Webpack и позволяют контролировать баланс между автоматической
оптимизацией и явной архитектурной структурой.