Skip to content

Переход с версии v7

Если вы мигрируете с rolldown-vite — это был технический preview Rolldown для Vite 6 и 7, — то вам актуальны только разделы с бейджем NRV в заголовке.

Изменение целевых браузеров по умолчанию NRV

Значение по умолчанию для build.target и 'baseline-widely-available' обновлено до более новых версий браузеров:

  • Chrome 107 → 111
  • Edge 107 → 111
  • Firefox 104 → 114
  • Safari 16.0 → 16.4

Эти версии браузеров соответствуют наборам функций Baseline, классифицируемых как широко доступные на 1 января 2026. Другими словами, все они были выпущены примерно два с половиной года назад.

Rolldown

Vite 8 использует инструменты на базе Rolldown и Oxc вместо esbuild и Rollup.

Поэтапная миграция

Пакет rolldown-vite реализует Vite 7 с Rolldown, но без остальных изменений Vite 8. Его можно использовать как промежуточный шаг при переходе на Vite 8. Чтобы перейти с обычного Vite 7 на rolldown-vite, смотрите руководство по интеграции Rolldown в документации Vite 7.

Если вы мигрируете с rolldown-vite на Vite 8, достаточно откатить изменения зависимостей в package.json и обновиться до Vite 8:

json
{
  "devDependencies": {
    "vite": "npm:rolldown-vite@7.2.2"
    "vite": "^8.0.0"
  }
}

Оптимизатор зависимостей теперь использует Rolldown

Для предварительной оптимизации зависимостей теперь используется Rolldown вместо esbuild. Для обратной совместимости Vite по-прежнему поддерживает optimizeDeps.esbuildOptions, автоматически преобразуя его в optimizeDeps.rolldownOptions. Опция optimizeDeps.esbuildOptions теперь считается устаревшей и будет удалена в будущем — рекомендуем перейти на optimizeDeps.rolldownOptions.

Следующие опции преобразуются автоматически:

Получить опции, которые подставил слой совместимости, можно из хука configResolved:

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

Трансформации JavaScript с помощью Oxc

Теперь для трансформации JavaScript используется Oxc вместо esbuild. Для обратной совместимости Vite по-прежнему поддерживает опцию esbuild, автоматически преобразуя её в oxc. Опция esbuild теперь считается устаревшей и будет удалена в будущем — рекомендуем перейти на oxc.

Следующие опции преобразуются автоматически:

Опция esbuild.supported не поддерживается Oxc. Если она вам нужна, смотрите oxc-project/oxc#15373.

Получить опции, которые подставил слой совместимости, можно из хука configResolved:

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

На данный момент Oxc-трансформер не поддерживает понижение нативных декораторов, так как мы ждём дальнейшего продвижения спецификации (см. oxc-project/oxc#9170).

Обходное решение для понижения нативных декораторов

Пока можно использовать Babel или SWC для понижения нативных декораторов.

Использование Babel:

bash
$ npm install -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash
$ yarn add -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash
$ pnpm add -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash
$ bun add -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash
$ deno add -D npm:@rolldown/plugin-babel npm:@babel/plugin-proposal-decorators
vite.config.ts
ts
import { defineConfig } from 'vite'
import babel from '@rolldown/plugin-babel'

function decoratorPreset(options: Record<string, unknown>) {
  return {
    preset: () => ({
      plugins: [['@babel/plugin-proposal-decorators', options]],
    }),
    rolldown: {
      // Выполнять эту трансформацию только если файл содержит декоратор.
      filter: {
        code: '@',
      },
    },
  }
}

export default defineConfig({
  plugins: [babel({ presets: [decoratorPreset({ version: '2023-11' })] })],
})

Использование SWC:

bash
$ npm install -D @rollup/plugin-swc @swc/core
bash
$ yarn add -D @rollup/plugin-swc @swc/core
bash
$ pnpm add -D @rollup/plugin-swc @swc/core
bash
$ bun add -D @rollup/plugin-swc @swc/core
bash
$ deno add -D npm:@rollup/plugin-swc npm:@swc/core
js
import { defineConfig, withFilter } from 'vite'

export default defineConfig({
  // ...
  plugins: [
    withFilter(
      swc({
        swc: {
          jsc: {
            parser: { decorators: true, decoratorsBeforeExport: true },
            transform: { decoratorVersion: '2023-11' },
          },
        },
      }),
      // Выполнять эту трансформацию только если файл содержит декоратор.
      { transform: { code: '@' } },
    ),
  ],
})

Резервные варианты с esbuild

esbuild больше не используется Vite напрямую и становится опциональной зависимостью. Если ваш плагин использует функцию transformWithEsbuild, необходимо установить esbuild как devDependency. Сама функция transformWithEsbuild объявлена устаревшей и будет удалена в будущем. Рекомендуем перейти на новую функцию transformWithOxc.

Минификация JavaScript с помощью Oxc

Для минификации JavaScript теперь используется Oxc Minifier вместо esbuild. Можно временно вернуться к esbuild через устаревшую опцию build.minify: 'esbuild'. Эта опция будет удалена в будущем, и вам потребуется установить esbuild как devDependency, так как Vite больше не зависит от него напрямую.

Если вы использовали опции esbuild.minify* для управления минификацией, теперь используйте build.rolldownOptions.output.minify. Если использовали esbuild.drop, теперь доступны опции build.rolldownOptions.output.minify.compress.drop*.

Сокращение имён свойств (property mangling) и связанные с ним опции не поддерживаются Oxc. Если они вам нужны — смотрите oxc-project/oxc#15375.

esbuild и Oxc Minifier делают немного разные предположения об исходном коде. Если подозреваете, что минификатор ломает ваш код, сравните эти предположения:

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

Минификация CSS с помощью Lightning CSS

По умолчанию для минификации CSS теперь используется Lightning CSS. Вернуться к esbuild можно через опцию build.cssMinify: 'esbuild'. При этом потребуется установить esbuild как devDependency.

Lightning CSS по умолчанию использует более современные CSS-конструкции. Из-за этого размер минифицированного CSS-бандла иногда может немного вырасти.

Единообразная совместимость с CommonJS

Импорт default из модуля CommonJS (CJS) теперь обрабатывается единообразно.

Если выполняется одно из следующих условий, импорт default — это значение module.exports импортируемого CJS-модуля. В противном случае импорт default — это значение module.exports.default импортируемого CJS-модуля:

  • Импортирующий файл имеет расширение .mjs или .mts.
  • Ближайший package.json для импортирующего файла содержит поле type со значением module.
  • Значение module.exports.__esModule импортируемого CJS-модуля не равно true.
Предыдущее поведение

В режиме разработки, если выполнялось одно из следующих условий, импорт default — это значение module.exports импортируемого CJS-модуля. В противном случае импорт default — это значение module.exports.default импортируемого CJS-модуля:

  • Импортирующий файл включён в оптимизацию зависимостей и имеет расширение .mjs или .mts.
  • Импортирующий файл включён в оптимизацию зависимостей и ближайший package.json для него содержит поле type со значением module.
  • Значение module.exports.__esModule импортируемого CJS-модуля не равно true.

В режиме сборки условия были:

  • Значение module.exports.__esModule импортируемого CJS-модуля не равно true.
  • Свойство default у module.exports не существует.

(при условии, что build.commonjsOptions.defaultIsModuleExports не изменено со значения по умолчанию 'auto')

Подробности об этой проблеме — в документации Rolldown.

Это изменение может сломать существующий код, импортирующий CJS-модули. Для временного возврата к старому поведению можно использовать устаревшую опцию legacy.inconsistentCjsInterop: true. Если вы обнаружили пакет, который пострадал от этого изменения — сообщите об этом автору пакета или отправьте ему пулреквест, обязательно приложив ссылку на документацию Rolldown выше, чтобы автор понял контекст.

Удалено определение формата модуля по содержимому файла

Раньше, когда в package.json одновременно присутствовали поля browser и module, Vite выбирал нужное поле, заглядывая в содержимое файла (и обычно брал ESM-файл для браузера). Такое поведение было введено из-за того, что некоторые пакеты использовали module для указания ESM-файла под Node.js, а другие — browser для UMD-файла под браузер. Поскольку современное поле exports решает эту проблему и уже широко принято, Vite больше не применяет эту эвристику и строго следует порядку в опции resolve.mainFields. Если вы полагались на прежнее поведение — используйте resolve.alias для сопоставления нужного поля с файлом или применяйте патч через менеджер пакетов (например, patch-package, pnpm patch).

Сохранение вызовов require для внешних модулей

Вызовы require для внешних модулей теперь сохраняются как require и не преобразуются в import. Это сделано для сохранения правильной семантики require. Если нужно всё-таки преобразовать их в import — используйте встроенный плагин Rolldown esmExternalRequirePlugin, который переэкспортируется из vite.

js
import { defineConfig, esmExternalRequirePlugin } from 'vite'

export default defineConfig({
  // ...
  plugins: [
    esmExternalRequirePlugin({
      external: ['react', 'vue', /^node:/],
    }),
  ],
})

См. подробности в документации Rolldown.

import.meta.url в форматах UMD / IIFE

Свойство import.meta.url больше не заменяется полифиллом в форматах вывода UMD / IIFE. По умолчанию оно заменяется на undefined. Если нужно сохранить прежнее поведение, используйте опцию define вместе с build.rolldownOptions.output.intro. Подробности — в документации Rolldown.

Удалена опция build.rollupOptions.watch.chokidar

Опция build.rollupOptions.watch.chokidar удалена. Переходите на build.rolldownOptions.watch.watcher.

Удалена объектная форма build.rollupOptions.output.manualChunks, а функциональная форма помечена как устаревшая

Объектная форма опции output.manualChunks больше не поддерживается. Функциональная форма output.manualChunks помечена как устаревшая (deprecated). Rolldown предлагает более гибкую опцию codeSplitting. Подробности о codeSplitting смотрите в документации Rolldown: Manual Code Splitting - Rolldown.

build() выбрасывает BundleError

Это изменение касается только пользователей JS API.

build() теперь выбрасывает BundleError вместо «сырой» ошибки, возникшей в плагине. BundleError типизирован как Error & { errors?: RolldownError[] } и оборачивает отдельные ошибки в массив errors. Если вам нужны конкретные ошибки, вам необходимо обратиться к свойству .errors:

js
try {
  await build()
} catch (e) {
  if (e.errors) {
    for (const error of e.errors) {
      console.log(error.code) // код ошибки
    }
  }
}

Поддержка типов модулей и их автоопределение

Это изменение касается только авторов плагинов.

Rolldown имеет экспериментальную поддержку типов модулей, аналогичную опции loader в esbuild. Из-за этого Rolldown теперь автоматически определяет тип модуля по расширению файла. Если в хуках load или transform вы преобразуете содержимое других типов модулей в JavaScript, может потребоваться явно указывать 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', 
      }
    }
  },
}

Следующие опции объявлены устаревшими и будут удалены в будущем:

  • build.rollupOptions → переименована в build.rolldownOptions
  • worker.rollupOptions переименована в worker.rolldownOptions
  • build.commonjsOptions теперь не делает ничего (no-op)
  • build.dynamicImportVarsOptions.warnOnError: теперь не делает ничего (no-op)
  • resolve.alias[].customResolver: Вместо этого используйте собственный плагин с хуком resolveId и опцией enforce: 'pre'

Удалённые устаревшие функции NRV

Передача URL в import.meta.hot.accept больше не поддерживается. Пожалуйста, передавайте id вместо этого

Расширенные возможности

Эти нарушающие совместимость изменения затронут лишь небольшое количество проектов:

  • Extglobs пока не поддерживаются (rolldown-vite#365)
  • Наследуемые пространства имён TypeScript поддерживаются только частично. Подробности смотрите в документации Oxc Transformer.
  • define не делит ссылку на объекты: если передать объект в define, каждая переменная получит свою копию объекта. Подробности — в документации Oxc Transformer.
  • Изменения в объекте bundle (объект, передаваемый в хуки generateBundle / writeBundle и возвращаемый функцией build):
    • назначение bundle[foo] = … больше не поддерживается (Rollup тоже не рекомендовал). Используйте this.emitFile().
    • ссылка на объект не сохраняется между хуками (rolldown-vite#410)
    • structuredClone(bundle) падает с DataCloneError. Эта возможность удалена. Клонируйте через structuredClone({ ...bundle }) (rolldown-vite#128)
  • Все параллельные хуки Rollup теперь работают как последовательные. Подробности — в документации Rolldown.
  • Директива "use strict"; иногда не вставляется. Подробности — в документации Rolldown.
  • Трансформация в ES5 и ниже с помощью plugin-legacy не поддерживается (rolldown-vite#452)
  • Передача одного и того же браузера с разными версиями в build.target теперь вызывает ошибку: раньше esbuild брал последнюю версию, что, скорее всего, не было желаемым поведением.
  • Функции, которые Rolldown и Vite больше не поддерживают:
  • Функции parseAst / parseAstAsync объявлены устаревшими в пользу parseSync / parse, у которых больше возможностей.
  • Комментарии удаляются до хука renderChunk, а не после хука renderChunk
  • Комментарии, кроме перечисленных здесь, перемещаются, в то время как Rollup удаляет комментарии только если удалён соответствующий код

Переход с v6

Сначала ознакомьтесь с Руководством по переходу с v6 в документации Vite v7, чтобы увидеть необходимые изменения для переноса вашего приложения на Vite 7, а затем продолжите с изменениями на этой странице.