В режиме разработки Rollup функционирует как инкрементальный бандлер, реагирующий на изменения файлов через механизм watch. Основная задача dev-окружения — обеспечить быстрый цикл: изменение кода → пересборка → обновление браузера без ручного перезапуска.
Типовая схема включает три слоя:
Rollup сам по себе не является сервером и не управляет браузерной перезагрузкой, поэтому интеграция строится через плагины и внешние HTTP-серверы.
Механизм watch активируется через CLI или API:
rollup -c -w
или через конфигурацию:
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'esm',
sourcemap: true
},
watch: {
include: 'src/**',
clearScreen: false
}
}
Ключевые особенности:
include и
excludeWatch-режим является базой для всех dev-инструментов, включая live reload и dev server интеграции.
Rollup не предоставляет HTTP-сервера, поэтому применяется
rollup-plugin-serve.
Базовая конфигурация:
import serve from 'rollup-plugin-serve';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: true
},
plugins: [
serve({
open: true,
port: 3000,
contentBase: ['dist'],
verbose: true
})
]
};
Функциональность dev server слоя:
Ограничения:
Для автоматического обновления страницы используется
rollup-plugin-livereload.
import livereload from 'rollup-plugin-livereload';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: true
},
plugins: [
serve({
contentBase: 'dist',
port: 3000
}),
livereload({
watch: 'dist',
delay: 200
})
]
};
Механизм работы:
Варианты поведения:
Типовая архитектура dev-контура строится на взаимодействии трёх компонентов:
Последовательность событий:
src/module.jsdist/bundle.jsdistКритический момент — задержки пересборки. При больших проектах
целесообразно настраивать debounce через
livereload.delay.
В классическом Rollup нет полноценного Hot Module Replacement. Это влияет на UX разработки:
Частично проблема решается сторонними решениями:
Однако архитектурно Rollup ориентирован на build-time оптимизацию, а не runtime патчи модулей.
Более гибкий подход — внешний сервер на Node.js (Express/Fastify) с интеграцией Rollup API.
Пример структуры:
import express from 'express';
import { watch } from 'rollup';
const app = express();
app.use(express.static('dist'));
const watcher = watch({
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'esm',
sourcemap: true
}
});
watcher.on('event', (event) => {
if (event.code === 'BUNDLE_END') {
// отправка сигнала через WebSocket
}
});
app.listen(3000);
Преимущества такой схемы:
Dev-среда часто требует проксирования запросов к backend:
import { createProxyMiddleware } from 'http-proxy-middleware';
app.use('/api', createProxyMiddleware({
target: 'http://localhost:8080',
changeOrigin: true
}));
Rollup-плагины напрямую не решают эту задачу, поэтому прокси всегда выносится на уровень сервера.
При использовании watch + livereload важны следующие аспекты:
1. Сокращение области наблюдения
watch: {
include: 'src/**',
exclude: 'node_modules/**'
}
2. Разделение конфигураций
3. Использование кеша Rollup автоматически кеширует граф, но плагины могут нарушать инкрементальность при неправильной реализации transform.
4. Минимизация плагинов в dev режиме Некоторые плагины (minify, terser) замедляют пересборку и должны отключаться.
Sourcemaps являются ключевым элементом интеграции:
output: {
sourcemap: true
}
Особенности:
При dev-сценариях чаще используется inline sourcemaps, в production — external.
1. Двойной reload Возникает при одновременном использовании нескольких watch-инстансов или плагинов livereload.
2. Задержка обновления Связана с накоплением нескольких rebuild событий. Решается debounce или throttle.
3. Потеря состояния dev server При пересборке server не обновляет статические ссылки, если кеш браузера не инвалидируется.
4. Конфликты портов Serve и внешние серверы могут конкурировать за один порт.
Разделение конфигураций:
Dev-конфигурация:
Production:
Rollup часто используется как underlying bundler в более высокоуровневых инструментах. В таких системах dev-server слой может быть полностью заменён:
При этом Rollup остаётся ответственным исключительно за модульный граф и генерацию бандла, а весь runtime слой выносится наружу.