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 для понижения нативных декораторов. SWC быстрее Babel, но не поддерживает самую свежую версию спецификации декораторов, которую поддерживает esbuild.

Спецификация декораторов несколько раз обновлялась после достижения stage 3. Поддерживаемые инструментами версии:

  • "2023-11" — поддерживают esbuild, TypeScript 5.4+ и Babel
  • "2023-05" — поддерживает TypeScript 5.2+
  • "2023-01" — поддерживает TypeScript 5.0+
  • "2022-03" — поддерживает SWC

Различия между версиями описаны в руководстве Babel по версиям декораторов.

Использование 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 },
            // ПРИМЕЧАНИЕ: SWC пока не поддерживает версию '2023-11'.
            transform: { decoratorVersion: '2022-03' },
          },
        },
      }),
      // Выполнять эту трансформацию только если файл содержит декоратор.
      { 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, у которых больше возможностей.

Переход с v6

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