Skip to content

Продакшен-сборка

Когда приходит время развернуть продакшен-версию вашего приложения, просто выполните команду vite build. По умолчанию она использует <root>/index.html в качестве точки входа для сборки и создает пакет приложения, который подходит для развёртывания на статическом хостинге. Ознакомьтесь с разделом Развёртывание статического сайта для получения инструкций по популярным сервисам.

Совместимость с браузерами

Продакшен-сборка предполагает поддержку современного JavaScript. По умолчанию Vite нацелен на браузеры, которые поддерживают встроенные ES-модули, встроенный динамический импорт ESM и import.meta:

  • Chrome >=87
  • Firefox >=78
  • Safari >=14
  • Edge >=88

Вы можете указать пользовательские цели через опцию конфигурации build.target, где самой низкой целью является es2015.

Обратите внимание, что по умолчанию Vite обрабатывает только синтаксические преобразования и не включает полифиллы. Вы можете ознакомиться с https://cdnjs.cloudflare.com/polyfill/, который автоматически генерирует пакеты полифиллов на основе строки UserAgent браузера пользователя.

Поддержка устаревших браузеров может быть обеспечена с помощью пакета @vitejs/plugin-legacy, который автоматически генерирует устаревшие чанки и соответствующие полифиллы для функций языка ES. Устаревшие чанки загружаются условно только в браузерах, которые не поддерживают встроенный ESM.

Публичный базовый путь

Если вы развёртываете свой проект под вложенным публичным путём, просто укажите опцию конфигурации base, и все пути к ресурсам будут переписаны соответственно. Эта опция также может быть указана в качестве флага командной строки, например, vite build --base=/my/public/path/.

URL-адреса ресурсов, импортируемых через JS, ссылки url() в CSS и ссылки на ресурсы в ваших .html файлах автоматически корректируются с учётом этой опции во время сборки.

Исключение составляют случаи, когда вам нужно динамически конкатенировать URL-адреса на лету. В этом случае вы можете использовать глобально инжектированную переменную import.meta.env.BASE_URL, которая будет публичным базовым путём. Обратите внимание, что эта переменная статически заменяется во время сборки, поэтому она должна появляться точно в том виде, в каком есть (т. е. import.meta.env['BASE_URL'] не сработает).

Для более продвинутого управления базовым путём ознакомьтесь с Расширенными параметрами базового пути.

Настройка сборки

Сборку можно настроить с помощью различных параметров конфигурации. В частности, вы можете напрямую настроить основные параметры Rollup через build.rollupOptions:

js
export default defineConfig({
  build: {
    rollupOptions: {
      // https://rollupjs.org/configuration-options/
    }
  }
})

Например, можно указать несколько выходных данных Rollup с плагинами, которые применяются только во время сборки.

Стратегия разбиения на чанки

Вы можете настроить, как чанки разбиваются, используя build.rollupOptions.output.manualChunks (см. документацию Rollup). Если вы используете фреймворк, обратитесь к его документации для настройки разбиения чанков.

Обработка ошибок загрузки

Vite генерирует событие vite:preloadError, когда не удаётся загрузить динамические импорты. event.payload содержит оригинальную ошибку импорта. При вызове event.preventDefault() ошибка не будет выброшена.

js
window.addEventListener('vite:preloadError', (event) => {
  window.location.reload() // например, обновим страницу
})

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

Пересборка при изменении файлов

Вы можете включить наблюдатель Rollup с помощью команды vite build --watch. Либо вы можете напрямую настроить основные параметры наблюдателя (WatcherOptions) через опцию build.watch:

js
// vite.config.js
export default defineConfig({
  build: {
    watch: {
      // https://rollupjs.org/configuration-options/#watch
    }
  }
})

С включенным флагом --watch изменения в файле vite.config.js, а также в любых файлах, подлежащих объединению, приведут к пересборке.

Многостраничное приложение

Предположим, у вас есть следующая структура проекта:

├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
    ├── index.html
    └── nested.js

Во время разработки просто перейдите или создайте ссылку на /nested/ — это работает как ожидается, так же, как и для обычного статического файлового сервера.

Во время сборки всё, что вам нужно сделать, это указать несколько .html файлов в качестве точек входа:

js
// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html')
      }
    }
  }
})

Если вы укажете другую корневую директорию, помните, что __dirname всё равно будет указывать на папку вашего файла vite.config.js при разрешении входных путей. Поэтому вам нужно будет добавить вашу запись root в аргументы для resolve.

Обратите внимание, что для HTML файлов Vite игнорирует имя, указанное для входа в объекте rollupOptions.input, и вместо этого учитывает разрешённый идентификатор файла при генерации HTML-ресурса в папке dist. Это обеспечивает согласованную структуру с тем, как работает dev-сервер.

Режим библиотеки

Когда вы разрабатываете библиотеку, ориентированную на браузер, вы, вероятно, проводите большую часть времени на тестовой/демонстрационной странице, которая импортирует вашу фактическую библиотеку. С Vite вы можете использовать ваш index.html для этой цели, чтобы получить плавный процесс разработки.

Когда приходит время упаковать вашу библиотеку для распространения, используйте опцию конфигурации build.lib. Убедитесь, что вы также исключили любые зависимости, которые не хотите включать в вашу библиотеку, например, vue или react:

js
// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    lib: {
      // Также может быть словарем или массивом нескольких точек входа
      entry: resolve(__dirname, 'lib/main.js'),
      name: 'MyLib',
      // соответствующие расширения будут добавлены
      fileName: 'my-lib'
    },
    rollupOptions: {
      // убедитесь, что вы исключили зависимости, которые не должны быть объединены
      // в вашу библиотеку
      external: ['vue'],
      output: {
        // Предоставьте глобальные переменные для использования в сборке UMD
        // для исключённых зависимостей
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
})

Файл входа будет содержать экспорты, которые могут быть импортированы пользователями вашего пакета:

js
// lib/main.js
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export { Foo, Bar }

Запуск команды vite build с этой конфигурацией использует предустановку Rollup, ориентированную на создание библиотек, и производит два формата пакетов: es и umd (настраиваемые через build.lib):

$ vite build
building for production...
dist/my-lib.js      0.08 kB / gzip: 0.07 kB
dist/my-lib.umd.cjs 0.30 kB / gzip: 0.16 kB

Рекомендуемый package.json для вашей библиотеки:

json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.umd.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.umd.cjs"
    }
  }
}

Или, если вы хотите предоставить несколько точек входа:

json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.cjs"
    },
    "./secondary": {
      "import": "./dist/secondary.js",
      "require": "./dist/secondary.cjs"
    }
  }
}

Расширения файлов

Если в package.json не указано "type": "module", Vite сгенерирует разные расширения файлов для совместимости с Node.js. .js станет .mjs, а .cjs станет .js.

Переменные окружения

В режиме библиотеки все использования import.meta.env.* статически заменяются при создании продакшен-сборки. Однако использования process.env.* не заменяются, чтобы потребители вашей библиотеки могли динамически изменять их. Если это нежелательно, вы можете использовать define: { 'process.env.NODE_ENV': '"production"' }, например, чтобы статически заменить их, или использовать esm-env для лучшей совместимости со сборщиками и средами выполнения.

Расширенное использование

Режим библиотеки включает в себя простую и предвзятую конфигурацию для библиотек, ориентированных на браузер и JS-фреймворки. Если вы разрабатываете библиотеки, не предназначенные для браузера, или вам требуются сложные процессы сборки, вы можете использовать Rollup или esbuild напрямую.

Расширенные параметры базового пути

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

Эта функция является экспериментальной. Оставьте отзыв.

Для сложных случаев использования развёрнутые ресурсы и публичные файлы могут находиться в разных путях, например, для использования различных стратегий кэширования. Пользователь может выбрать развёртывание в трех разных случаях:

  • Сгенерированные HTML файлы входа (которые могут обрабатываться во время серверного рендеринга)
  • Сгенерированные хэшированные ресурсы (JS, CSS и другие типы файлов, такие как изображения)
  • Скопированные публичные файлы

Одного статического базового пути недостаточно в этих сценариях. Vite предоставляет экспериментальную поддержку для расширенных базовых опций во время сборки, используя experimental.renderBuiltUrl.

ts
import type { UserConfig } from 'vite'
// prettier-ignore
const config: UserConfig = {
// ---cut-before---
experimental: {
  renderBuiltUrl(filename, { hostType }) {
    if (hostType === 'js') {
      return { runtime: `window.__toCdnUrl(${JSON.stringify(filename)})` }
    } else {
      return { relative: true }
    }
  },
},
// ---cut-after---
}

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

ts
import type { UserConfig } from 'vite'
import path from 'node:path'
// prettier-ignore
const config: UserConfig = {
// ---cut-before---
experimental: {
  renderBuiltUrl(filename, { hostId, hostType, type }) {
    if (type === 'public') {
      return 'https://www.domain.com/' + filename
    } else if (path.extname(hostId) === '.js') {
      return { runtime: `window.__assetsPath(${JSON.stringify(filename)})` }
    } else {
      return 'https://cdn.domain.com/assets/' + filename
    }
  },
},
// ---cut-after---
}

Обратите внимание, что переданное значение filename является декодированным URL, и если функция возвращает строку URL, она также должна быть декодирована. Vite автоматически обработает кодирование при рендеринге URL. Если возвращается объект с runtime, кодирование должно обрабатываться вами самостоятельно в необходимых местах, так как код во время выполнения будет рендериться как есть.

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