Механизм SplitChunksPlugin отвечает за автоматическое
разбиение модулей на отдельные чанки с целью переиспользования кода,
уменьшения общего размера бандла и оптимизации загрузки приложения. В
современных сборках Webpack этот плагин является ключевым инструментом
оптимизации, так как позволяет извлекать повторяющиеся зависимости,
выделять vendor-код и формировать эффективную структуру кэшируемых
файлов.
В процессе сборки Webpack формирует граф зависимостей, где каждый модуль может быть включён в один или несколько чанков. Без оптимизации один и тот же модуль часто попадает в разные бандлы, увеличивая общий размер выдачи и ухудшая кэширование.
SplitChunksPlugin анализирует этот граф и принимает
решение о том, какие модули:
cacheGroupsПосле анализа создаются новые чанки, содержащие общие зависимости, а исходные чанки переподключаются через runtime-обвязку Webpack.
Настройка осуществляется через
optimization.splitChunks:
module.exports = {
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
Значение chunks: 'all' включает анализ как синхронных,
так и асинхронных импортов, что делает поведение наиболее агрессивным с
точки зрения выделения общего кода.
Другие варианты:
async — только динамически загружаемые модули
(import())initial — только синхронные зависимостиОпределяет минимальный размер модуля или группы модулей для выделения в отдельный чанк.
splitChunks: {
minSize: 20000
}
Модули меньше указанного значения не будут вынесены в отдельный файл, даже если подходят под другие критерии.
Определяет минимальное количество чанков, в которых модуль должен встретиться, чтобы быть выделенным.
splitChunks: {
minChunks: 2
}
Если модуль используется только один раз, он остаётся внутри исходного чанка.
Ограничивают количество параллельных загрузок:
splitChunks: {
maxAsyncRequests: 30,
maxInitialRequests: 30
}
Эти параметры управляют балансом между количеством файлов и скоростью загрузки.
Позволяет задавать имя создаваемого чанка.
splitChunks: {
name: 'common'
}
На практике чаще используется функция или отключение фиксированного имени для более гибкой генерации хэшей.
Основной механизм управления поведением SplitChunksPlugin реализован
через cacheGroups. Это набор правил, определяющих, какие
модули и куда выносить.
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
В этом примере все зависимости из node_modules
собираются в отдельный чанк vendors.
Каждая группа может содержать:
test — фильтр модулей (регулярное выражение или
функция)name — имя чанкаchunks — тип чанков (async, initial, all)priority — приоритет применения правилenforce — принудительное применение без учёта
глобальных ограниченийreuseExistingChunk — переиспользование существующего
чанкаЕсли модуль подходит под несколько правил, используется параметр
priority.
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
name: 'vendor',
priority: 10
},
common: {
test: /src/,
name: 'common',
priority: 5
}
}
}
Модуль из node_modules попадёт в vendor,
так как у него более высокий приоритет.
Одной из ключевых задач SplitChunksPlugin является выделение повторяющихся модулей внутри собственного кода приложения.
splitChunks: {
cacheGroups: {
common: {
minChunks: 2,
chunks: 'all',
name: 'common',
enforce: true
}
}
}
Такой подход позволяет вынести утилиты, хелперы и повторяющиеся компоненты в отдельный файл, уменьшая дублирование.
Часто используется стратегия отделения сторонних библиотек:
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
enforce: true
}
}
}
Это улучшает кэширование, так как зависимости из
node_modules изменяются значительно реже, чем код
приложения.
Различие режимов влияет на стратегию загрузки:
async — оптимизация только для динамических
импортовinitial — влияет на основной entry bundleall — объединяет оба режима и обеспечивает максимальное
разделениеПример динамического разделения:
import('lodash').then(({ default: _ }) => {
console.log(_.chunk([1, 2, 3], 2));
});
При использовании async Webpack создаст отдельный чанк
для lodash, загружаемый по требованию.
Оптимизация повторного использования уже созданных чанков:
splitChunks: {
cacheGroups: {
common: {
reuseExistingChunk: true
}
}
}
Если модуль уже выделен в отдельный чанк, Webpack не создаёт дубликат, а подключает существующий.
Параметр enforce отключает часть глобальных ограничений
(minSize, minChunks):
splitChunks: {
cacheGroups: {
largeLib: {
test: /large-library/,
name: 'large-lib',
enforce: true
}
}
}
Это полезно для критически важных библиотек, которые нужно вынести независимо от размера.
Поведение можно описать последовательностью шагов:
cacheGroupsminChunks и minSizemaxInitialRequests и
maxAsyncRequestssplitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /node_modules/,
name: 'vendors'
},
common: {
minChunks: 2,
name: 'common'
}
}
}
splitChunks: {
chunks: 'all',
minSize: 30000,
cacheGroups: {
react: {
test: /react|react-dom/,
name: 'react',
priority: 20
},
vendors: {
test: /node_modules/,
name: 'vendors',
priority: 10
},
common: {
minChunks: 2,
name: 'common',
priority: 5
}
}
}
splitChunks: {
chunks: 'all',
maxInitialRequests: 20,
maxAsyncRequests: 30,
cacheGroups: {
vendors: {
test: /node_modules/,
name(module) {
const match = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/);
return match ? match[1] : 'vendors';
}
}
}
}
В этом случае каждая библиотека может быть вынесена в отдельный чанк для максимального кэширования.
После выделения чанков Webpack генерирует runtime-код, который отвечает за:
Этот слой обеспечивает прозрачное выполнение кода независимо от того, в каком чанке он находится.
import() является естественной точкой разделения кода,
но SplitChunksPlugin может дополнительно оптимизировать
такие чанки:
Приводит к созданию множества мелких файлов, что увеличивает количество HTTP-запросов и ухудшает производительность.
Без явных правил Webpack использует дефолтную стратегию, которая не всегда оптимальна для крупных приложений.
Разбиение каждой зависимости на отдельный файл может привести к перегрузке сети при первом запуске.
Большое количество initial чанков может замедлить загрузку главной страницы.
SplitChunksPlugin напрямую влияет на эффективность долгосрочного кэширования:
Правильное разделение снижает объём повторно загружаемых данных при обновлении приложения.
В крупных проектах SplitChunksPlugin применяется совместно с:
import()[contenthash]prefetch, preload)webpack-bundle-analyzer)Такая комбинация позволяет выстраивать структуру сборки, в которой: