Skip to content

Интеграция Rolldown

Vite планирует интегрировать Rolldown — JavaScript-бандлер на Rust, чтобы улучшить производительность сборки и расширить возможности.

Что такое Rolldown?

Rolldown — это современный высокопроизводительный JavaScript-бандлер, написанный на Rust. Он разработан как замена Rollup с сохранением совместимости, но с существенным приростом производительности.

Ключевые принципы Rolldown:

  • Скорость: Реализация на Rust для максимальной производительности
  • Совместимость: Работает с существующими плагинами Rollup
  • Оптимизация: включает функции, выходящие за рамки возможностей esbuild и Rollup

Почему Vite переходит на Rolldown

  1. Унификация: Сейчас Vite использует esbuild для предварительной сборки зависимостей и Rollup для продакшн-сборки. Rolldown объединит эти процессы в один высокопроизводительный инструмент, упрощая архитектуру.

  2. Производительность: Реализация на Rust дает значительный прирост скорости по сравнению с JavaScript-решениями. Хотя конкретные показатели зависят от проекта, первые тесты показывают впечатляющие результаты.

  3. Дополнительные возможности: Rolldown предоставляет функции, недоступные в Rollup или esbuild, такие как расширенный контроль разделения чанков, встроенный HMR (горячая замена модулей) и плагин Module Federation.

Подробнее о причинах создания Rolldown можно узнать в официальной документации.

Преимущества тестирования rolldown-vite

  • Более быстрая сборка, особенно для крупных проектов
  • Улучшение будущей интеграции Rolldown в Vite, благодаря обратной связи
  • Подготовка своих проектов к официальному переходу на Rolldown

Как попробовать Rolldown

Версия Vite на базе Rolldown доступна в виде отдельного пакета rolldown-vite. Если у вас есть vite в качестве прямой зависимости, вы можете создать псевдоним для пакета vite, указывающий на rolldown-vite в package.json вашего проекта — это должно сработать как полная замена без дополнительной настройки:

json
{
  "dependencies": {
    "vite": "^7.0.0"
    "vite": "npm:rolldown-vite@latest"
  }
}

Если вы используете Vitepress или мета-фреймворк, в котором vite указан как peer-зависимость, вам нужно переопределить зависимость vite в вашем package.json. Это работает немного по-разному в зависимости от используемого менеджера пакетов:

json
{
  "overrides": {
    "vite": "npm:rolldown-vite@latest"
  }
}
json
{
  "resolutions": {
    "vite": "npm:rolldown-vite@latest"
  }
}
json
{
  "pnpm": {
    "overrides": {
      "vite": "npm:rolldown-vite@latest"
    }
  }
}
json
{
  "overrides": {
    "vite": "npm:rolldown-vite@latest"
  }
}

После добавления переопределений переустановите зависимости и запускайте сервер разработки или сборку проекта как обычно. Дополнительные изменения конфигурации не требуются.

Известные ограничения

Хотя Rolldown стремится быть полной заменой Rollup, некоторые функции всё ещё находятся в разработке, а также есть небольшие преднамеренные различия в поведении. Полный список можно найти в этом PR на GitHub, который регулярно обновляется.

Предупреждения валидации опций

Rolldown выводит предупреждение при передаче неизвестных или некорректных опций. Поскольку некоторые опции, доступные в Rollup, не поддерживаются Rolldown, вы можете столкнуться с предупреждениями в зависимости от опций, которые вы или используемый мета-фреймворк задали. Ниже приведён пример такого предупреждения:

Warning validate output options.

  • For the "generatedCode". Invalid key: Expected never but received "generatedCode".

Если вы не передаёте эту опцию самостоятельно, проблема должна быть исправлена в используемом фреймворке.

Различия в API

От manualChunks к advancedChunks

Хотя Rolldown поддерживает опцию manualChunks, также доступную в Rollup, она помечена как устаревшая. Вместо неё предлагается использовать более детализированную настройку через опцию advancedChunks, которая больше похожа на splitChunk в webpack:

js
// Устаревшая конфигурация (Rollup)
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (/\/react(?:-dom)?/.test(id)) {
            return 'vendor'
          }
        }
      }
    }
  }
}

// Обновлённая конфигурация (Rolldown)
export default {
  build: {
    rollupOptions: {
      output: {
        advancedChunks: {
          groups: [{ name: 'vendor', test: /\/react(?:-dom)?/ }]
        }
      }
    }
  }
}

Производительность

rolldown-vite ориентирован на обеспечение совместимости с существующей экосистемой, поэтому настройки по умолчанию направлены на максимально плавный переход. Дополнительный прирост производительности можно получить, перейдя на более быстрые внутренние плагины на базе Rust и применив другие кастомизации.

Подключение нативных плагинов

Благодаря Rolldown и Oxc, различные внутренние плагины Vite, такие как плагин alias или resolve, были переведены на Rust. Нативные плагины теперь включены по умолчанию, с установленным значением по умолчанию 'v1'.

Если вы столкнулись с какими-либо проблемами, попробуйте изменить опцию experimental.enableNativePlugin в конфигурации Vite на 'resolver' или false в качестве временного решения. Обратите внимание, что эта опция будет удалена в будущем.

Использование React refresh transform от Oxc

@vitejs/plugin-react v5.0.0+ использует React refresh transform от Oxc. Если вы не используете плагины Babel (включая React compiler), теперь вся трансформация будет выполняться Oxc, что улучшит производительность сборки без каких-либо изменений, кроме обновления @vitejs/plugin-react.

Если вы используете @vitejs/plugin-react-swc без плагинов SWC и пользовательских настроек SWC, вы можете перейти на плагин @vitejs/plugin-react, чтобы задействовать Oxc.

Плагин @vitejs/plugin-react-oxc устарел

Ранее мы рекомендовали использовать @vitejs/plugin-react-oxc для задействования React refresh transform от Oxc. Однако мы объединили реализацию в @vitejs/plugin-react, чтобы упростить переход на rolldown-vite. @vitejs/plugin-react-oxc теперь устарел и больше не будет обновляться.

Обёртка withFilter

Авторы плагинов могут использовать возможность фильтрации хуков, чтобы снизить издержки на взаимодействие между средами выполнения Rust и JavaScript. Однако, если какие-то используемые вами плагины пока ещё не применяют эту функцию, но вы всё равно хотите получить от неё выгоду, вы можете обернуть плагин вручную, используя обёртку withFilter:

js
// В вашем vite.config.ts
import { withFilter, defineConfig } from 'vite'
import svgr from 'vite-plugin-svgr'

export default defineConfig({
  plugins: [
    // Загружаем плагин `svgr` только для файлов, которые заканчиваются на `.svg?react`
    withFilter(
      svgr({
        /*...*/
      }),
      { load: { id: /\.svg\?react$/ } },
    ),
  ],
})

Сообщение о проблемах

Поскольку это экспериментальная интеграция, вы можете столкнуться с проблемами. Если это произошло, пожалуйста, сообщайте о них в репозитории vitejs/rolldown-vite, а не в основном репозитории Vite.

При сообщении о проблемах пожалуйста, следуйте соответствующему шаблону issue и укажите запрашиваемую информацию, которая обычно включает:

  • Минимальный пример для воспроизведения проблемы
  • Данные о вашем окружении (ОС, версия Node, пакетный менеджер)
  • Соответствующие сообщения об ошибках или логи

Для оперативного обсуждения и решения проблем присоединяйтесь к Discord Rolldown.

Политика версионирования

Политика версионирования rolldown-vite согласована с основным пакетом Vite: его мажорные и минорные версии синхронизированы с обычным Vite. Это гарантирует, что все фичи, появившиеся в конкретной минорной версии Vite, также будут присутствовать в соответствующей минорной версии rolldown-vite. Однако важно отметить, что патч-версии не синхронизированы между этими двумя проектами. Если вы хотите узнать, была ли конкретная правка из обычного Vite включена в rolldown-vite, вы всегда можете проверить отдельный changelog rolldown-vite.

Также обратите внимание, что rolldown-vite считается экспериментальным проектом. В связи с этим возможны обратимо несовместимые изменения даже в патч-версиях. Кроме того, rolldown-vite получает обновления только для самой последней минорной версии — даже важные багфиксы и обновления безопасности не выпускаются для более старых мажорных или минорных версий.

Планы на будущее

Пакет rolldown-vite — это временное решение для сбора отзывов и стабилизации интеграции Rolldown. В будущем эта функциональность будет перенесена в основной репозиторий Vite.

Мы призываем вас опробовать rolldown-vite и внести вклад в его развитие через отзывы и сообщения о проблемах.

В будущем мы также представим «режим полной сборки» (Full Bundle Mode) для Vite, который будет обслуживать собранные файлы как в продакшене, так и в режиме разработки.

Зачем нужен режим полной сборки?

Vite известен своим подходом к серверу разработки без сборки (unbundled), что стало одной из основных причин его скорости и популярности при первом выпуске. Изначально этот подход был экспериментом, чтобы проверить, насколько можно повысить производительность сервера разработки без традиционной сборки.

Однако по мере роста масштабов и сложности проектов возникли две основные проблемы:

  1. Несоответствие между разработкой и продакшеном: JavaScript без сборки в разработке и собранный пакет в продакшене ведут себя по-разному. Это может приводить к ошибкам, которые проявляются только в продакшене, усложняя отладку.

  2. Снижение производительности в режиме разработки: Подход без сборки приводит к раздельной загрузке каждого модуля, что создаёт большое количество сетевых запросов. Хотя это не влияет на продакшен, это вызывает значительные накладные расходы при запуске сервера разработки и обновлении страницы в процессе разработки. Особенно заметно это проявляется в крупных приложениях, где необходимо обрабатывать сотни или даже тысячи отдельных запросов. Эти узкие места становятся ещё более серьёзными при использовании сетевых прокси, что приводит к увеличению времени перезагрузки и ухудшению опыта разработчиков.

Благодаря интеграции с Rolldown у нас появилась возможность унифицировать процесс разработки и продакшена, сохраняя при этом фирменную производительность Vite. Режим полной сборки позволит использовать собранные файлы не только в продакшене, но и во время разработки, сочетая преимущества обоих подходов:

  • Быстрый запуск даже для крупных приложений
  • Единообразное поведение в разработке и продакшене
  • Снижение сетевой нагрузки при обновлении страниц
  • Сохранение эффективного HMR поверх ESM-вывода

Изначально режим полной сборки будет доступен как опциональная функция. Как и в случае с интеграцией Rolldown, мы планируем сделать его режимом по умолчанию после сбора отзывов и достижения необходимой стабильности работы.

Руководство для авторов плагинов и фреймворков

СОВЕТ

Данный раздел в первую очередь будет полезен разработчикам плагинов и создателям фреймворков. Обычным пользователям можно смело пропустить эту часть.

Обзор ключевых изменений

  • Для сборки теперь используется Rolldown (ранее использовался Rollup)
  • Для оптимизации теперь используется Rolldown (ранее использовался esbuild)
  • Поддержка CommonJS теперь обрабатывается Rolldown (ранее использовался @rollup/plugin-commonjs)
  • Для понижения синтаксиса теперь используется Oxc (ранее использовался esbuild)
  • Для минификации CSS по умолчанию используется Lightning CSS (ранее использовался esbuild)
  • Для минификации JS по умолчанию теперь используется Oxc minifier (ранее использовался esbuild)
  • Для сборки конфигурации теперь используется Rolldown (ранее использовался esbuild)

Определение rolldown-vite

ПРЕДУПРЕЖДЕНИЕ

В большинстве случаев вам не нужно определять, работает ли ваш плагин с rolldown-vite или обычным vite. Следует стремиться к одинаковому поведению в обеих средах без условных ветвлений.

Если вам всё же требуется разное поведение для rolldown-vite, есть два способа его определить:

Проверка существования this.meta.rolldownVersion:

js
const plugin = {
  resolveId() {
    if (this.meta.rolldownVersion) {
      // логика для rolldown-vite
    } else {
      // логика для rollup-vite
    }
  },
}

СОВЕТ

Начиная с Vite 7.0.0, this.meta доступен во всех хуках. В предыдущих версиях this.meta не был доступен в специфичных для Vite хуках, таких как хук config.


Проверка существования экспорта rolldownVersion:

js
import * as vite from 'vite'

if (vite.rolldownVersion) {
  // логика для rolldown-vite
} else {
  // логика для rollup-vite
}

Если у вас есть vite в зависимостях (не peer dependency), экспорт rolldownVersion полезен, так как его можно использовать из любого места вашего кода.

Игнорирование проверки опций в Rolldown

Как уже упоминалось выше, Rolldown выводит предупреждение при передаче неизвестных или некорректных опций.

Эту проблему можно решить, условно передавая опцию после проверки, что код выполняется с rolldown-vite, как показано выше.

transformWithEsbuild требует отдельной установки esbuild

Поскольку Vite больше не использует esbuild, теперь esbuild является необязательной одноранговой зависимостью. Если ваш плагин использует transformWithEsbuild, необходимо добавить esbuild в зависимости плагина или пользователю придется установить его вручную.

Рекомендуемый путь миграции — использовать новую экспортируемую функцию transformWithOxc, которая работает с Oxc вместо esbuild.

Слой совместимости для опций esbuild

Rolldown-Vite включает слой совместимости, преобразующий опции esbuild в соответствующие опции Oxc или rolldown. Как протестировано в ecosystem-ci, это работает во многих случаях, включая простые плагины esbuild. Однако важно отметить, что поддержка опций esbuild будет удалена в будущем. Мы рекомендуем использовать соответствующие опции Oxc или rolldown. Вы можете получить опции, установленные слоем совместимости, через хук configResolved.

js
const plugin = {
  name: 'log-config',
  configResolved(config) {
    console.log('options', config.optimizeDeps, config.oxc)
  },
},

Фильтрация хуков

Rolldown представил функцию фильтрации хуков для уменьшения накладных расходов на взаимодействие между средами выполнения Rust и JavaScript. Использование этой функции позволяет повысить производительность вашего плагина. Эта возможность также поддерживается в Rollup 4.38.0+ и Vite 6.3.0+. Для обеспечения обратной совместимости вашего плагина со старыми версиями убедитесь, что фильтрация также выполняется внутри обработчиков хуков.

СОВЕТ

Пакет @rolldown/pluginutils экспортирует несколько утилит для фильтрации хуков, таких как exactRegex и prefixRegex.

Преобразование контента в JavaScript в хуках load или transform

Если вы преобразуете контент других типов в JavaScript в хуках load или transform, возможно, потребуется добавить moduleType: 'js' к возвращаемому значению.

js
const plugin = {
  name: 'txt-loader',
  load(id) {
    if (id.endsWith('.txt')) {
      const content = fs.readFile(id, 'utf-8')
      return {
        code: `export default ${JSON.stringify(content)}`,
        moduleType: 'js', 
      }
    }
  },
}

Это связано с тем, что Rolldown поддерживает модули, отличные от JavaScript, и определяет тип модуля по расширению файла, если он не указан явно.

Выпущено под лицензией MIT.