Динамические чанки в Rollup появляются в результате использования
динамического импорта (import()), когда код разбивается на
отдельные части, загружаемые по требованию. Каждый такой модульный
фрагмент превращается в отдельный файл при сборке. В отличие от
статических entry-бандлов, их количество и структура зависят от графа
зависимостей и точек разделения кода.
Ключевая особенность динамических чанков заключается в том, что их имена не фиксированы заранее — они генерируются на этапе сборки, исходя из конфигурации и правил именования.
При встрече динамического импорта Rollup:
import('./module.js')
создаёт отдельный чанк. Если не задано дополнительной конфигурации, имя определяется автоматически:
По умолчанию результат выглядит примерно так:
module-a1b2c3.js
Хеш в имени гарантирует уникальность и помогает кэшированию.
Основной инструмент управления именованием динамических чанков —
output.chunkFileNames.
export default {
output: {
chunkFileNames: '[name]-[hash].js'
}
}
[name] — логическое имя чанка[hash] — хеш содержимого[format] — формат сборки (cjs, esm и др.)[extname] — расширение файла[name][name] формируется не всегда очевидно. Rollup пытается
вывести его из:
manualChunksЕсли имя не удаётся определить, используется fallback вроде
chunk.
Хотя manualChunks чаще используется для группировки, он
напрямую влияет на именование динамических чанков.
export default {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor'
}
}
}
}
Результат:
vendor-[hash].js
Возвращаемая строка становится:
[name]Это один из самых надёжных способов контролировать динамические чанки.
Для production-сборок важно избегать «прыгающих» имён.
Без контроля именования возможны ситуации:
Rollup может формировать имя чанка на основе относительного пути:
src/components/Button.js → components-Button.js
Но при глубокой вложенности это приводит к:
Поэтому такой подход обычно комбинируется с
manualChunks.
Хотя entryFileNames напрямую не влияет на динамические
чанки, он важен для согласованности именования:
export default {
output: {
entryFileNames: '[name]-entry.js',
chunkFileNames: '[name]-chunk-[hash].js'
}
}
Это создаёт единый стиль:
Если Rollup не может определить имя, он создаёт техническое имя:
chunk-abc123.js
Это происходит, когда:
manualChunksRollup может использовать имя экспортируемого модуля как основу чанка.
Пример:
export function init() {}
При динамическом импорте:
import('./init.js')
возможное имя чанка:
init-[hash].js
Если же модуль агрегирует несколько экспортов, имя становится менее предсказуемым.
Разделение по смыслу:
manualChunks(id) {
if (id.includes('chart')) return 'charts'
if (id.includes('auth')) return 'auth'
}
Результат:
charts-[hash].js
auth-[hash].js
Плюсы:
Минусы:
Вынос зависимостей:
manualChunks(id) {
if (id.includes('node_modules')) return 'vendor'
}
Результат:
vendor-[hash].js
Используется для:
chunkFileNames: 'chunks/[name]-[hash].js'
Преимущества:
Каждый import() создаёт отдельную точку разбиения:
button.oncl ick = async () => {
const module = await import('./heavy.js')
}
Имя чанка зависит от:
./heavy.jsmanualChunkschunkFileNamesЕсли динамически импортируемый модуль тянет зависимости:
A → import B → import C
Rollup:
Если же B и C используются в других чанках, происходит пересечение и дополнительное разделение.
При сложной конфигурации возможны конфликты:
[name]Решения:
[hash]Шаблон можно заменить функцией:
export default {
output: {
chunkFileNames(chunkInfo) {
return `chunks/${chunkInfo.name}-${chunkInfo.hash}.js`
}
}
}
namefacadeModuleIdmodulesisDynamicEntryimportsЭто позволяет строить сложную логику именования.
Для крупных приложений применяются правила:
Пример:
ui-button-[hash].js
feature-auth-login-[hash].js
Это делает структуру сборки сопоставимой с архитектурой проекта.
При включении:
preserveModules: true
Rollup перестаёт агрессивно объединять модули.
Имена становятся ближе к файловой структуре:
src/utils/math.js → utils/math.js
Динамические чанки при этом могут дробиться сильнее, но становятся более предсказуемыми.
Комбинированная конфигурация:
export default {
output: {
manualChunks(id) {
if (id.includes('node_modules')) return 'vendor'
},
chunkFileNames: 'chunks/[name]-[hash].js'
}
}
Поведение:
Типичные проблемы:
[name] → конфликтыПри изменении кода:
[hash] обновляется точечноЕсли имена не детерминированы, пересборка может затронуть больше файлов, чем необходимо.
Именование динамических чанков в Rollup всегда балансирует между:
На практике наиболее устойчивый результат достигается комбинацией:
manualChunks для логики разбиенияchunkFileNames для структуры[hash] для кэш-устойчивости