Vite 8 объединил свои инструменты для сборки в Rolldown — что сломалось
Vite 8 по умолчанию использует режим Rolldown как для разработки, так и для производства. Проблемы с взаимодействием с настоящим CJS, сложности при миграции чанков и список проверок перед тем, как доверять результатам автоматизированных тестов.
В течение многих лет Vite тайно использовал два разных инструмента для сборки кода — один во время разработки, другой при выпуске продукта. Rolldown устраняет это разделение. Ускорения действительно реальны, так же как и список проблем.
Многие команды знают симптомы, но не могут указать причину: локальный сервер работает нормально, а в продакшене возникают проблемы, и причина не в опечатке. Среда выполнения, которая обслуживала модули во время разработки, и инструментарий для пакетирования их в продакшен не соглашались по поводу определённого крайнего случая. В Vite это несоответствие было структурным: esbuild использовался во время разработки, а Rollup — для выпуска, причём связующее звено было настолько хорошим, что различия оставались незаметными — пока это не прекратилось.
Vite 8 устраняет это различие с помощью одного инструмента на языке Rust — Rolldown. Результаты тестов впечатляют, как и список приложений, которые перестали работать, когда годы использования двух разных инструментов внезапно потеряли свою скрытность. Знание обеих сторон помогает осуществить обновление без неожиданных проблем.
Что изменилось в Vite 8
Стратегия использования двух движков казалась разумной в 2020 году. Создание собственного инструмента для сборки кода с нуля — это многолетняя работа. esbuild уже быстро развивался, а Rollup уже имел экосистему плагинов. Соединение их вместе казалось прагматичным решением. Однако это создавало постоянный риск: два инструмента могли по-разному обрабатывать одни и те же исходные файлы, особенно при взаимодействии с CommonJS — неудобном мостике между модулями require() и современным форматом ESM.
Rolldown представляет собой решение всей этой проблемы в рамках одного движка. Он реализован на языке Rust, имеет API в стиле Rollup (большинство плагинов продолжают работать), стабильная версия 1.0 вышла 7 мая 2026 года с фиксированным API, предназначенным для промышленного использования. Сам Vite 8 стабилизировался 12 марта 2026 года и сделал Rolldown стандартным вариантом без возможности выбора другого инструмента. Процессы преобразования и минификации, ранее выполнявшиеся с помощью esbuild, теперь осуществляются с использованием Oxc — ещё одного инструмента на Rust от компании VoidZero (той же, что создала Rolldown).
Заголовок: сборки для производства могут загружаться в 10–30 раз быстрее, чем классический Rollup. Режим разработки — это более скромный результат. «Режим полного пакета» упаковывает приложение во время разработки так же, как и для производства, вместо того чтобы предоставлять сырые файлы формата ESM по отдельности. Предварительные данные показывают ускорение запуска примерно в 3 раза, загрузки при полном обновлении — примерно на 40%, а количество сетевых запросов — примерно в 10 раз меньше. Большие кодовые базы уже давно не справлялись с использованием формата ESM без упаковки во время разработки; этот инструмент закрывает этот пробел.
Структурное преимущество заключается в простоте: один движок для обоих режимов. Старые ошибки типа «интероперабельность в режиме разработки ≠ интероперабельность в производственном режиме» становятся невозможными, поскольку больше нет второго инструмента упаковки, с которым могли бы возникнуть разногласия.
Что на самом деле сломалось
Миграция не была бесплатной, и игнорирование этого факта никак не поможет тем, кто планирует обновление.
Более строгая интеграция CommonJS нарушила работу пакетов. Неоднозначные экспорты в формате CJS обрабатываются иначе, чем в старой комбинации esbuild+Rollup. При отсутствии поля module.exports.__esModule и свойства default Rolldown может привязать импорт к всему объекту module.exports, вместо того чтобы, как это делала более либеральная система, предположить наличие значения по умолчанию:
// This used to just work under Vite 7 (esbuild + Rollup)
import DOMPurify from 'dompurify';
DOMPurify.sanitize(input);
// Under Rolldown's stricter CJS interop, this can throw:
// TypeError: e is not a function
// because the import resolved to the whole exports object,
// not the function you expected
Опасное свойство этого класса: инструменты CI обычно его игнорируют. jsdom или имитированные тестовые среды редко запускают настоящий продакшн-артефакт. Ошибки возникают, когда браузер загружает собранный результат. Параметр legacy.inconsistentCjsInterop: true в Vite восстанавливает старое либеральное поведение, пока вы ищете проблемную зависимость.
manualChunks устарел в пользу advancedChunks. Это замещение не является простым поиском и заменой. Команды сталкивались с ошибкой ReferenceError: Cannot access 'x' before initialization из-за побочных эффектов, связанных с порядком чанков, после их перегруппировки, причем по крайней мере в одном отчете описывалось 575 чанков при стандартной схеме разбиения Rolldown до ручной настройки.
// Old, now-deprecated approach
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
}
// Rolldown's replacement - more powerful, but a real migration
build: {
rolldownOptions: {
output: {
advancedChunks: {
groups: [
{ name: 'vendor', test: /node_modules/, priority: 100 },
],
},
},
},
}
Зарегистрированный случай: библиотека Cloudflare @cloudflare/style-provider (гибрид ESM+CJS) столкнулась с ошибкой createRenderer is not a function, поскольку Rolldown генерировал анонимный, недоступный инициализатор для части кода на CJS. Патч привязал этот пакет к его версии на CJS в конфигурации Vite — обычный CJS через интероптацию Rolldown работал нормально, но гибридная форма — нет.
Внешний код приложения: нативный биндинг Rolldown на Rust не смог загрузиться в WebContainers StackBlitz, что привело к неработоспособности многих шаблонов среды разработки в браузере, пока проекты не переключились на Vite 7 в ожидании устранения проблемы разработчиками.
Чек-лист для более безопасной миграции
Команды, завершившие миграцию, сосредотачиваются на конкретных деталях, а не просто выполняют обновление и надеются на лучшее.
Таинственные ошибки вида «Vite 7 работает, Vite 8 не работает»: сначала попробуйте использовать experimental: { enableNativePlugin: false }. Теперь по умолчанию включены нативные плагины на Rust; их отключение помогает устранить значительное количество необъяснимых сбоев.
Перед развертыванием загрузите реальный производственный пакет в настоящем браузере. jsdom не сможет обнаружить классы для взаимодействия CJS, если вы не запустите собранный файл.
Рассматривайте изменение от manualChunks к advancedChunks как реальный проект с собственным этапом тестирования. Проблемы с порядком блоков кажутся нерешенными, пока не будет запущен определённый путь.
Снизьте риски с помощью rolldown-vite (Vite 7 + превью Rolldown) для тестирования вашего кодового базиса перед переходом на Vite 8.
Если какая-то критически важная зависимость ещё не готова к использованию с Rolldown, оставаться на Vite 7 для её обработки — разумный выбор; это лучше, чем создавать нестабильные решения в срочном порядке.
Кто может столкнуться с проблемами
Стандартные зависимости в формате ESM и простая/стандартная разбивка на чанки: обновления обычно проходят гладко, и одна лишь совместимость уже стоит усилий. Однако при наличии пользовательских параметров manualChunks, гибридных пакетов CJS/ESM или необычных сред выполнения (сандбоксы браузеров, WebContainers) необходимо учесть время миграции и протестировать результат в браузере. Такие сбои могут пройти проверку CI как успешные, но проявиться у реальных пользователей в финальных версиях приложения.
Более общий урок
Когда две системы, которые раньше маскировали недостатки друг друга, сливаются в одну, ранее невидимые швы сразу становятся заметными. Это не означает, что процесс объединения был ошибочным. Соответствие версий разработки и продакшена — это реальное улучшение структуры, а показатели скорости остаются на высоком уровне. Это значит, что фразы «мы устранили разногласия» и «во время перехода появится волна конкретных, выявимых багов» описывают один и тот же факт, но в разные даты. Скептицизм по отношению к методу Rolldown — неверная позиция; скептицизм по отношению к зеленому CI без производственного пакета, загружаемого в браузер, — верная.
Что указать в задании на миграцию
Опишите обновление как техническую изменение с критериями приемки, а не как увеличение зависимостей.
Рекомендуемые критерии:
- Производственная сборка должна завершаться при использовании метода Rolldown с теми же публичными ресурсами, которые вы ожидаете.
legacy.inconsistentCjsInterop с указанием ответственного лица и даты истечения срока действия.manualChunks заменяется на advancedChunks с проведением специального тестирования.Если какой-либо критерий не выполняется, следует оставаться на версии Vite 7 или rolldown-vite до тех пор, пока он не будет соблюдён. Релиз более быстрого пакетизатора, который нарушает работу в производственной среде, не является улучшением производительности.
Почему ошибки паритета кажутся личными
Разработчики доверяют локальному серверу. Когда локальный сервер и продакшен-версия перестают конфликтовать друг с другом, баги, которые раньше скрывались из-за этих конфликтов, проявляются в одном месте. Это может создать впечатление, что проблемы «возникли» из-за особенностей работы двойной схемы, хотя на самом деле они всегда существовали из-за неоднозначности CJS или структуры чанков. Называние таких паттернов снижает панику: вы не преследуете случайные регрессии, а выявляете проблемы, которые были скрыты в эпоху двойных двигателей.
Сохраняйте показатели скорости. Сохраняйте дизайн с одним двигателем. Просто не путайте отрицательные результаты тестов с доказательством того, что готовый продукт работает корректно.