Головна / Статті

Vite 8 об’єднав свої бандлери в Rolldown — що зламалося

Vite 8 за замовчуванням використовує режим Rolldown як для розробки, так і для продакшну. Проблеми зі взаємодією з справжнім CJS, підводні камені під час міграції чанків та перелік перевірок перед тим, як довіряти статусу «зелене CI».

Видавець: REACTAPP.TOP6 хв читання1296 слів

Джерела: Vite Merged Its Two Bundlers Into One. Here’s Everything That Broke.

Протягом багатьох років 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 не вдалося завантажити у StackBlitz WebContainers, що призвело до недії багатьох шаблонів для тестування в браузері, поки проекти не перейшли на 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 без продакшн-бундлу, завантаженого в браузері, — це правильна.

Що вказати у заявці на міграцію

Описуйте оновлення як інженерну зміну з критеріями прийняття, а не як підвищення версії залежностей.

Рекомендовані критерії:

  1. Будова версії для продакшну завершується за допомогою Rolldown із тими самими публічними ресурсами, яких ви очікуєте.
  • Критичні сценарії роботи користувача тестуються у реальному браузері з використанням створеного пакета (а не лише за допомогою тестів на одиницю).
  • Відомі гібридні залежності типу CJS або переименовуються, або оновлюються, або покриваються параметром legacy.inconsistentCjsInterop із вказаною особою, відповідальною за це, та терміном дії.
  • Стратегія формування частин пакета ретельно переглядається: або приймаються стандартні налаштування Rolldown після підрахунку кількості запитів, або параметр manualChunks замінюється на advancedChunks із спеціальним етапом тестування.
  • У середовищах, які не можуть завантажувати нативні компоненти (наприклад, деякі хостинги WebContainer), існують задокументовані рішення чи обхідні шляхи.
  • Якщо будь-який критерій не виконується, слід залишатися на версії Vite 7 або rolldown-vite доки він не буде задоволений. Випуск швидшого пакетузатора, який порушує функціонування в продакшені, не є покращенням продуктивності.

    Чому помилки паритету здаються особистими

    Розробники довіряють локальному серверу. Коли локальний сервер та продакшн-версія перестають „сперечатися“ між собою, баги, які раніше ховалися в цих суперечках, з’являються в одному місці. Це може здаватися так, ніби механізм Rolldown „ввів“ проблеми, які завжди існували через неоднозначності CJS чи структуру чанків. Назва цього явища зменшує паніку: ви не намагаєтесь знайти випадкові регресії, а лише виявляєте проблеми, які були приховані в епоху подвійних двигунів.

    Зберігайте показники швидкості. Зберігайте концепцію одного двигуна. Просто не плутайте позитивні результати тестування з доказом того, що готовий продукт функціонує належним чином.