Интеграция Rolldown
Vite планирует интегрировать Rolldown — JavaScript-бандлер на Rust, чтобы улучшить производительность сборки и расширить возможности.
Что такое Rolldown?
Rolldown — это современный высокопроизводительный JavaScript-бандлер, написанный на Rust. Он разработан как замена Rollup с сохранением совместимости, но с существенным приростом производительности.
Ключевые принципы Rolldown:
- Скорость: Реализация на Rust для максимальной производительности
- Совместимость: Работает с существующими плагинами Rollup
- Оптимизация: включает функции, выходящие за рамки возможностей esbuild и Rollup
Почему Vite переходит на Rolldown
Унификация: Сейчас Vite использует esbuild для предварительной сборки зависимостей и Rollup для продакшн-сборки. Rolldown объединит эти процессы в один высокопроизводительный инструмент, упрощая архитектуру.
Производительность: Реализация на Rust дает значительный прирост скорости по сравнению с JavaScript-решениями. Хотя конкретные показатели зависят от проекта, первые тесты показывают впечатляющие результаты.
Дополнительные возможности: Rolldown предоставляет функции, недоступные в Rollup или esbuild, такие как расширенный контроль разделения чанков, встроенный HMR (горячая замена модулей) и плагин Module Federation.
Подробнее о причинах создания Rolldown можно узнать в официальной документации.
Преимущества тестирования rolldown-vite
- Более быстрая сборка, особенно для крупных проектов
- Улучшение будущей интеграции Rolldown в Vite, благодаря обратной связи
- Подготовка своих проектов к официальному переходу на Rolldown
Как попробовать Rolldown
Версия Vite на базе Rolldown доступна в виде отдельного пакета rolldown-vite. Если у вас есть vite в качестве прямой зависимости, вы можете создать псевдоним для пакета vite, указывающий на rolldown-vite в package.json вашего проекта — это должно сработать как полная замена без дополнительной настройки:
{
"devDependencies": {
"vite": "^7.0.0"
"vite": "npm:rolldown-vite@latest"
}
}Пожалуйста, зафиксируйте версию!
Хотя в этих примерах используется @latest, мы рекомендуем использовать конкретный номер версии, чтобы избежать неожиданных критических изменений, поскольку пакет rolldown-vite считается экспериментальным.
Если вы используете Vitepress или мета-фреймворк, в котором vite указан как peer-зависимость, вам нужно переопределить зависимость vite в вашем package.json. Это работает немного по-разному в зависимости от используемого менеджера пакетов:
{
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}{
"resolutions": {
"vite": "npm:rolldown-vite@latest"
}
}{
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}
}{
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}После добавления переопределений переустановите зависимости и запускайте сервер разработки или сборку проекта как обычно. Дополнительные изменения конфигурации не требуются.
Если вы начинаете новый проект, вы можете использовать create-vite как обычно для rolldown-vite. Последняя версия спросит вас, использовать ли rolldown-vite или нет.
Известные ограничения
Хотя 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:
// Устаревшая конфигурация (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:
// В вашем 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), что стало одной из основных причин его скорости и популярности при первом выпуске. Изначально этот подход был экспериментом, чтобы проверить, насколько можно повысить производительность сервера разработки без традиционной сборки.
Однако по мере роста масштабов и сложности проектов возникли две основные проблемы:
Несоответствие между разработкой и продакшеном: JavaScript без сборки в разработке и собранный пакет в продакшене ведут себя по-разному. Это может приводить к ошибкам, которые проявляются только в продакшене, усложняя отладку.
Снижение производительности в режиме разработки: Подход без сборки приводит к раздельной загрузке каждого модуля, что создаёт большое количество сетевых запросов. Хотя это не влияет на продакшен, это вызывает значительные накладные расходы при запуске сервера разработки и обновлении страницы в процессе разработки. Особенно заметно это проявляется в крупных приложениях, где необходимо обрабатывать сотни или даже тысячи отдельных запросов. Эти узкие места становятся ещё более серьёзными при использовании сетевых прокси, что приводит к увеличению времени перезагрузки и ухудшению опыта разработчиков.
Благодаря интеграции с 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:
const plugin = {
resolveId() {
if (this.meta.rolldownVersion) {
// логика для rolldown-vite
} else {
// логика для rollup-vite
}
},
}СОВЕТ
Начиная с Vite 7.0.0, this.meta доступен во всех хуках. В предыдущих версиях this.meta не был доступен в специфичных для Vite хуках, таких как хук config.
Проверка существования экспорта rolldownVersion:
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.
const plugin = {
name: 'log-config',
configResolved(config) {
console.log('options', config.optimizeDeps, config.oxc)
},
},Фильтрация хуков
Rolldown ввёл функцию фильтрации хуков, чтобы уменьшить накладные расходы на взаимодействие между средами выполнения Rust и JavaScript. Эта функция позволяет плагинам указывать шаблоны, определяющие, когда должны вызываться хуки, улучшая производительность за счёт избежания ненужных вызовов хуков.
См. руководство по фильтрам хуков для получения дополнительной информации.
Преобразование контента в JavaScript в хуках load или transform
Если вы преобразуете контент других типов в JavaScript в хуках load или transform, возможно, потребуется добавить moduleType: '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, и определяет тип модуля по расширению файла, если он не указан явно.