В механизме разделения кода Webpack ключевую роль играет настройка
optimization.splitChunks.chunks, определяющая, какие типы
модулей будут учитываться при формировании отдельных чанков. Значение
этого параметра влияет на стратегию кеширования, загрузку асинхронных
зависимостей и структуру итогового бандла.
Доступные значения: initial, async,
all.
Режим initial ограничивает область анализа только
синхронными зависимостями, которые входят в стартовый граф
приложения.
При chunks: 'initial' Webpack:
import()), формирующие
async chunks;Типичная структура при нескольких entry:
entry A → module shared → vendor
entry B → module shared → vendor
Общие зависимости выносятся в отдельный чанк, но только если они используются в синхронных графах.
module.exports = {
optimization: {
splitChunks: {
chunks: 'initial'
}
}
};
Режим async ориентирован на код, который загружается
лениво через динамические импорты.
При chunks: 'async' Webpack:
import();Если несколько динамических импортов используют одинаковый модуль, он может быть вынесен в отдельный async chunk:
route A (lazy) ─┐
├── shared module → async shared chunk
route B (lazy) ─┘
module.exports = {
optimization: {
splitChunks: {
chunks: 'async'
}
}
};
Режим all является наиболее агрессивной стратегией
разделения кода.
При chunks: 'all' Webpack:
entry A ─┐
├── shared vendor chunk
entry B ─┘
route X (async) ─┐
├── shared async chunk
route Y (async) ─┘
entry + async могут разделять общие зависимости
module.exports = {
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
initial — только стартовые чанкиasync — только динамические чанкиall — весь граф модулейinitial — средняяasync — высокая для ленивых модулейall — максимальная глобальнаяinitial — возможно в async частиasync — возможно в initial частиall — минимальноеБиблиотеки типа react, lodash,
axios попадают только в синхронный граф.
Та же библиотека может оказаться в нескольких async чанках, если используется в разных lazy маршрутах.
Vendor-логика выносится в единые shared chunks:
vendors~main.js
vendors~routes.js
Оптимален для:
Проблема: слабая оптимизация lazy частей.
Оптимален для:
Проблема: дублирование общего кода между entry.
Оптимален для:
Проблема: более сложная стратегия кеширования, возможен рост количества мелких чанков.
Параметр chunks всегда работает в связке с
cacheGroups.
Пример:
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
},
common: {
name: 'common',
minChunks: 2,
chunks: 'all'
}
}
}
}
Даже при глобальном chunks: 'all', отдельные cacheGroups
могут переопределять поведение и дополнительно уточнять стратегию
разделения.
При all:
При initial:
При async:
Webpack сначала строит полный dependency graph, после чего:
chunks;При all чаще появляются:
vendors~common~vendors~main~routeЭто результат пересечения нескольких графов.
При all и агрессивных cacheGroups возможно появление
слишком большого числа мелких файлов:
При initial и async часто наблюдается
дублирование lodash, date-fns и аналогичных библиотек.
При сложных зависимостях и all структура может
становиться менее очевидной без анализа stats.json.