Фаза завершения сборки в Rollup начинается после генерации графа модулей и формирования итоговых бандлов и охватывает набор хуков, отвечающих за запись файлов и постобработку результата. Среди них ключевую роль играют два плагин-хука: writeBundle и closeBundle. Эти хуки относятся к финальной стадии пайплайна и используются для операций, которые должны выполняться после того, как Rollup сформировал выходные файлы.
Для понимания роли writeBundle и closeBundle важно учитывать общий порядок выполнения ключевых хуков:
writeBundle и closeBundle находятся в самом конце процесса, когда:
writeBundle используется для выполнения действий сразу после того, как Rollup записал выходные файлы. Это точка расширения, позволяющая работать с уже сформированным результатом сборки.
Ключевая особенность:
writeBundle вызывается после записи файлов, но до полного завершения процесса сборки.
writeBundle(outputOptions, bundle)
outputOptions Объект с конфигурацией выходного бандла:
bundle Объект, содержащий информацию о всех сгенерированных чанках и ассетах:
async)После сборки файлы могут быть отправлены в CDN или облачное хранилище.
export default function uploadPlugin() {
return {
name: 'upload-plugin',
async writeBundle(options, bundle) {
for (const [fileName, output] of Object.entries(bundle)) {
if (output.type === 'asset') {
await uploadToCDN(fileName, output.source);
}
}
}
};
}
writeBundle удобно использовать для анализа размера бандла.
export default function bundleReport() {
return {
name: 'bundle-report',
writeBundle(options, bundle) {
const report = Object.entries(bundle).map(([name, item]) => {
return {
name,
type: item.type,
size: item.type === 'chunk' ? item.code.length : item.source.length
};
});
console.table(report);
}
};
}
Например, переименование, логирование, генерация манифестов.
export default function manifestPlugin() {
return {
name: 'manifest-plugin',
writeBundle(options, bundle) {
const manifest = {};
for (const file of Object.values(bundle)) {
if (file.type === 'chunk') {
manifest[file.fileName] = file.facadeModuleId;
}
}
fs.writeFileSync('dist/manifest.json', JSON.stringify(manifest, null, 2));
}
};
}
closeBundle — это финальный хук жизненного цикла сборки Rollup. Он вызывается после завершения всех операций записи и является точкой завершения процесса.
Ключевая особенность:
closeBundle вызывается один раз в конце всей сборки, независимо от количества output-конфигураций.
closeBundle()
или
async closeBundle() {}
| Характеристика | writeBundle | closeBundle |
|---|---|---|
| Частота вызова | Для каждого output | Один раз за сборку |
| Доступ к bundle | Есть | Нет |
| Фаза | После записи файлов | Финальное завершение |
| Асинхронность | Поддерживается | Поддерживается |
closeBundle часто используется для освобождения ресурсов, созданных во время сборки.
export default function tempPlugin() {
return {
name: 'temp-plugin',
buildStart() {
this.tempFiles = [];
},
generateBundle(_, bundle) {
// создание временных файлов
},
closeBundle() {
for (const file of this.tempFiles || []) {
fs.unlinkSync(file);
}
}
};
}
closeBundle используется как финальная точка интеграции с пайплайнами.
export default function ciNotifier() {
return {
name: 'ci-notifier',
async closeBundle() {
await notifyCI({
status: 'success',
timestamp: Date.now()
});
}
};
}
В отличие от writeBundle, closeBundle подходит для глобальных логов сборки.
export default function finalLogger() {
return {
name: 'final-logger',
closeBundle() {
console.log('Сборка завершена полностью');
}
};
}
В режиме rollup --watch:
Ошибки внутри closeBundle:
closeBundle() {
try {
cleanupTemp();
} catch (e) {
console.error('Ошибка очистки:', e);
}
}
Эти два хука образуют последовательный финальный слой:
Типичная цепочка финальных операций:
Подходит, если требуется:
Подходит, если требуется:
В реальных плагинах оба хука часто используются совместно:
export default function advancedPlugin() {
let stats = [];
return {
name: 'advanced-plugin',
writeBundle(options, bundle) {
stats = Object.keys(bundle);
},
closeBundle() {
fs.writeFileSync('stats.json', JSON.stringify(stats));
console.log('Статистика записана');
}
};
}