Иконка подарка

Весенняя распродажа! Скидка 15% по промокоду

до 01.04.2026

Конфигурация Vite - vite config

27 марта 2026
Автор

Олег Марков

Введение

Файл конфигурации Vite — это центральное место, где вы управляете поведением сборщика: указываете корневую директорию проекта, настраиваете алиасы, подключаете плагины, меняете порт dev-сервера, настраиваете сборку и многие другие вещи.

Смотрите, я покажу вам, как сделать конфигурацию понятной, предсказуемой и управляемой. В этой статье мы пройдемся по основным возможностям vite.config, разберем, как его организовывать в реальных проектах и как не запутаться в десятках опций.

Базовое устройство vite.config

Где лежит конфиг и как он подхватывается

По умолчанию Vite ищет конфиг в корне проекта. Поддерживаются разные форматы:

  • vite.config.js
  • vite.config.mjs
  • vite.config.ts
  • vite.config.cjs

На практике чаще всего вы будете использовать TypeScript-конфиг:

// vite.config.ts
import { defineConfig } from "vite"

// Функция defineConfig улучшает подсказки типов и проверку
export default defineConfig({
  // Здесь будут ваши настройки
})

Обратите внимание: можно обойтись и без defineConfig, просто экспортируя объект, но с ним редактор кода даст вам более точные подсказки.

Структура объекта конфигурации

Конфиг — это один объект с несколькими крупными разделами:

  • root — корневая директория проекта
  • base — базовый публичный путь
  • resolve — настройки модулей и алиасов
  • server — параметры dev-сервера
  • build — параметры продакшн-сборки
  • preview — настройки preview-сервера
  • plugins — плагины Vite
  • define — глобальные константы на этапе сборки
  • css — настройка обработки CSS
  • optimizeDeps — предоптимизация зависимостей
  • envDir, envPrefix — работа с env-переменными

Давайте разбираться по шагам.

Базовые настройки проекта

root и base

root — корень проекта

Если ваш фронтенд-код лежит не в корне репозитория, а, например, в папке frontend, можно явно указать корневую директорию для Vite:

// vite.config.ts
import { defineConfig } from "vite"
import { resolve } from "path"

export default defineConfig({
  // Указываем корень проекта для Vite
  root: resolve(__dirname, "frontend"),
})

Так Vite будет считать точкой входа именно эту папку: искать index.html, относительные пути и т. д.

base — базовый путь для ассетов

Параметр base задает "префикс" для всех импортируемых ресурсов (JS, CSS, картинки). Это важно, если приложение размещается не в корне домена.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  // Приложение будет доступно, например, по /my-app/
  base: "/my-app/",
})

В dev-режиме base влияет на пути в HTML и модулях, а при сборке на то, как будут генерироваться ссылки в итоговых файлах.

Если вы деплоите SPA в поддиректорию, не забудьте настроить base корректно, иначе ассеты "потеряются".

envDir и envPrefix

envDir — откуда брать .env файлы

По умолчанию Vite ищет .env файлы в корне конфигурации. Если вам нужно хранить их отдельно, можно указать каталог:

// vite.config.ts
import { defineConfig } from "vite"
import { resolve } from "path"

export default defineConfig({
  // Все .env файлы ищем в папке config/env
  envDir: resolve(__dirname, "config", "env"),
})

envPrefix — фильтрация переменных окружения

Для безопасности Vite по умолчанию экспортирует в клиент только переменные с префиксом VITE_. Этот префикс можно изменить или расширить:

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  // Будут доступны переменные VITE_* и FRONT_*
  envPrefix: ["VITE_", "FRONT_"],
})

В коде вы будете получать их так:

// main.ts
// Здесь мы читаем переменную окружения, которая попала в клиент
const apiUrl = import.meta.env.VITE_API_URL

Разрешение модулей и алиасы

resolve.alias — удобные пути к модулям

Чтобы вам не приходилось писать длинные относительные пути вроде ../../../components/Button, лучше настроить алиасы.

// vite.config.ts
import { defineConfig } from "vite"
import { resolve } from "path"

export default defineConfig({
  resolve: {
    alias: {
      // Здесь мы создаем алиас @ для src
      "@": resolve(__dirname, "src"),
      "@components": resolve(__dirname, "src/components"),
    },
  },
})

Теперь вы можете писать:

// Здесь мы используем алиас @components вместо относительного пути
import Button from "@components/Button"

Это делает код понятнее, а рефакторинг — проще.

resolve.extensions и dedupe

Дополнительно можно задать расширения по умолчанию и "объединить" несколько копий одной зависимости.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  resolve: {
    // Расширения, которые Vite будет подставлять автоматически
    extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json"],
    // Здесь мы говорим Vite использовать одну копию react и react-dom
    dedupe: ["react", "react-dom"],
  },
})

Это полезно при работе с monorepo или локально линкованными пакетами, чтобы не получить две разные копии React.

Конфигурация dev-сервера

Базовые опции server

Здесь вы управляете тем, как ведет себя Vite во время разработки: на каком порту работает, изменять ли файлы на диске, нужно ли HTTPS и так далее.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  server: {
    // Порт dev-сервера
    port: 3000,
    // Автоматически открывать браузер
    open: true,
    // Разрешать доступ не только с localhost
    host: true, // или "0.0.0.0"
    // Включить строгую проверку порта
    strictPort: true,
  },
})
  • host: true позволяет открыть приложение на мобильном устройстве в локальной сети
  • strictPort: если порт 3000 занят, Vite не будет искать следующий свободный, а завершит работу с ошибкой. Это удобно для стабильных окружений.

HTTPS и сертификаты

Если вам нужно проверить работу приложения по HTTPS (например, для OAuth или сервис-воркеров), вы можете включить его в dev-сервере:

// vite.config.ts
import { defineConfig } from "vite"
import fs from "fs"
import path from "path"

export default defineConfig({
  server: {
    https: {
      // Здесь мы читаем самоподписанный сертификат
      cert: fs.readFileSync(path.resolve(__dirname, "certs", "dev.crt")),
      key: fs.readFileSync(path.resolve(__dirname, "certs", "dev.key")),
    },
  },
})

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

Прокси для бэкенда

Очень частый сценарий — Vite обслуживает фронтенд, а API работает на другом порту (или домене). Чтобы не мучиться с CORS в dev-режиме, настройте прокси.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  server: {
    proxy: {
      // Все запросы, начинающиеся с /api, будут проксироваться
      "/api": {
        target: "http://localhost:8080",
        changeOrigin: true,
        // Здесь мы переписываем путь, убирая /api
        rewrite: (path) => path.replace(/^\/api/, ""),
      },
    },
  },
})

Теперь в коде вы можете обращаться к /api/users, а фактически запрос уйдет на http://localhost:8080/users.

Настройка сборки (build)

Главные параметры build

Смотрите, я покажу вам типичный блок build-конфигурации:

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  build: {
    // Выходная директория
    outDir: "dist",
    // Очищать ли директорию перед сборкой
    emptyOutDir: true,
    // Включить/отключить sourcemap
    sourcemap: true,
    // Минификация (esbuild или terser)
    minify: "esbuild",
    // Цель компиляции
    target: "es2017",
  },
})

Пояснения:

  • outDir — папка, куда Vite положит результат сборки
  • sourcemap — полезно включать на stage/staging окружениях
  • minify — можно выключить (false) для отладки или заменить на "terser", если нужен более тонкий контроль минификации
  • target — указывает, под какой JS-движок вы собираете проект (например, es2015, es2017, esnext)

Настройка Rollup через rollupOptions

Под капотом Vite использует Rollup для продакшн-сборки. Вы можете тонко управлять этим процессом через build.rollupOptions.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  build: {
    rollupOptions: {
      // Здесь мы определяем множественные точки входа
      input: {
        main: "index.html",
        admin: "admin/index.html",
      },
      output: {
        // Шаблон имен файлов
        entryFileNames: "assets/[name]-[hash].js",
        chunkFileNames: "assets/[name]-[hash].js",
        assetFileNames: "assets/[name]-[hash][extname]",
      },
    },
  },
})

Так вы можете собрать несколько страниц или приложений одним запуском Vite.

Library mode

Если вы пишете библиотеку, а не SPA, Vite тоже можно настроить под это.

// vite.config.ts
import { defineConfig } from "vite"
import { resolve } from "path"

export default defineConfig({
  build: {
    lib: {
      // Здесь мы указываем основной файл библиотеки
      entry: resolve(__dirname, "src/index.ts"),
      // Имя глобальной переменной для UMD/IIFE
      name: "MyLib",
      // Имена выходных файлов
      fileName: (format) => `my-lib.${format}.js`,
    },
    rollupOptions: {
      external: ["react", "react-dom"],
      output: {
        globals: {
          // Здесь мы говорим Rollup, как зовут externals в глобальном scope
          react: "React",
          "react-dom": "ReactDOM",
        },
      },
    },
  },
})

Такой режим удобен, если вы публикуете npm-пакет.

Работа с плагинами

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

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

Простейший пример — подключение плагина для React:

// vite.config.ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"

export default defineConfig({
  plugins: [
    // Здесь мы подключаем плагин React
    react(),
  ],
})

Для Vue будет аналогично:

// vite.config.ts
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"

export default defineConfig({
  plugins: [
    // Здесь мы подключаем поддержку файлов .vue
    vue(),
  ],
})

Собственный плагин Vite

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

// vite.config.ts
import { defineConfig, Plugin } from "vite"

function logImportsPlugin(): Plugin {
  return {
    name: "log-imports",
    // Этот хук вызывается для каждого импортируемого модуля
    load(id) {
      // Здесь мы выводим путь к модулю в консоль
      console.log("[log-imports]", id)
      // Возвращаем null, чтобы Vite продолжил обычную загрузку
      return null
    },
  }
}

export default defineConfig({
  plugins: [
    logImportsPlugin(),
  ],
})

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

Глобальные константы: define

Подстановка значений на этапе сборки

Секция define позволяет подменять выражения в коде на конкретные строковые значения. Это делается чисто на этапе сборки.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  define: {
    // Здесь мы создаем глобальную константу __BUILD_DATE__
    __BUILD_DATE__: JSON.stringify(new Date().toISOString()),
    // Переписываем process.env.NODE_ENV
    "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
  },
})

Теперь вы можете использовать это в коде:

// appInfo.ts
// Здесь мы выводим дату сборки
console.log("Build date:", __BUILD_DATE__)

Важно: define заменяет текст в коде, поэтому почти всегда значения нужно оборачивать в JSON.stringify, чтобы получить корректный JavaScript‑литерал.

Конфигурация CSS

Общие настройки css

В конфиге Vite есть отдельный раздел css, который управляет препроцессорами, модулями и пост-обработкой.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  css: {
    // Включаем CSS-модули по умолчанию только для файлов *.module.css
    modules: {
      scopeBehaviour: "local",
      // Здесь мы настраиваем формат локального имени класса
      generateScopedName: "[name]__[local]___[hash:base64:5]",
    },
  },
})

Препроцессоры: Sass, Less, Stylus

Допустим, вы используете Sass и вам нужно передавать в каждый файл общие переменные.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        // Здесь мы автоматически добавляем импорт переменных в каждый scss-файл
        additionalData: `@import "src/styles/variables.scss";`,
      },
    },
  },
})

Теперь вам не нужно вручную импортировать variables.scss в каждом файле.

PostCSS

Если вы используете Tailwind CSS, Autoprefixer или другие PostCSS-плагины, их можно настроить через postcss.config или прямо в vite.config.

// vite.config.ts
import { defineConfig } from "vite"
import autoprefixer from "autoprefixer"
import tailwindcss from "tailwindcss"

export default defineConfig({
  css: {
    postcss: {
      // Здесь мы подключаем плагины PostCSS
      plugins: [
        tailwindcss(),
        autoprefixer(),
      ],
    },
  },
})

Так вы получите единый контроль над всей обработкой стилей.

Оптимизация зависимостей: optimizeDeps

Зачем нужна предоптимизация

Vite использует ES-модули в dev-режиме. Однако многие пакеты из npm до сих пор публикуются в формате CommonJS или с тяжелым деревом зависимостей. Чтобы ускорить запуск dev-сервера, такие пакеты "предсобираются" с помощью esbuild.

Этим управляет секция optimizeDeps.

include и exclude

Если какая-то зависимость загружается медленно или странно, вы можете явно указать Vite, как с ней обращаться.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  optimizeDeps: {
    // Здесь мы явно просим Vite предоптимизировать эти зависимости
    include: [
      "lodash-es",
      "date-fns",
    ],
    // А эти, наоборот, исключаем из предоптимизации
    exclude: [
      "some-large-lib",
    ],
  },
})

Чаще всего вам это не понадобится, но при работе с "нестандартными" пакетами это может спасти время.

Конфигурация preview-сервера

После сборки Vite может запустить локальный сервер, который будет отдавать уже собранную версию приложения (а не dev‑версию). Это удобно для локального теста продакшн-сборки.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  preview: {
    // Порт preview-сервера
    port: 5000,
    // Разрешаем доступ из сети
    host: true,
  },
})

Вы запускаете его командой:

# Здесь мы запускаем preview-сервер
npm run build
npm run preview

Так вы увидите приложение максимально близко к тому, что будет на продакшене.

Конфиг как функция и режимы (mode)

Конфигурация в зависимости от режима

Очень часто настройки для dev, test и prod отличаются. В Vite вы можете экспортировать не объект, а функцию, которая получит контекст.

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig(({ command, mode }) => {
  // Здесь мы определяем, собираем ли мы приложение
  const isBuild = command === "build"
  // Здесь мы определяем, в каком режиме мы находимся
  const isProduction = mode === "production"

  return {
    base: isProduction ? "/app/" : "/",
    build: {
      sourcemap: !isProduction,
      minify: isProduction ? "esbuild" : false,
    },
    server: {
      port: isProduction ? 4000 : 3000,
    },
  }
})
  • command — "serve" или "build"
  • mode — текущий режим (по умолчанию: "development" для dev и "production" для build, но вы можете задавать свои)

Свои режимы и .env файлы

Режим можно указать явно:

# Здесь мы запускаем dev-сервер в режиме staging
vite --mode staging

Тогда Vite подхватит файлы:

  • .env.staging
  • .env.staging.local

И mode в конфиге будет "staging". Это позволяет делать тонкие настройки под конкретные окружения.

Организация конфигурации в крупных проектах

Разделение конфига на модули

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

// vite.config.ts
import { defineConfig } from "vite"
import baseConfig from "./config/vite.base"
import devConfig from "./config/vite.dev"
import prodConfig from "./config/vite.prod"

export default defineConfig(({ command, mode }) => {
  // Здесь мы выбираем нужный конфиг в зависимости от режима
  const envConfig = mode === "production" ? prodConfig : devConfig

  // Объединяем базовый конфиг с env-специфичным
  return {
    ...baseConfig,
    ...envConfig,
    // При необходимости вы можете докинуть что-то поверх
  }
})

Внутри vite.base.ts вы можете держать общие настройки: алиасы, плагины, CSS. В vite.dev.ts и vite.prod.ts — dev/production-специфику (порт, минификация, прокси).

Использование TypeScript для типовой безопасности

Чтобы не запутаться в полях конфига, удобно использовать типы из Vite:

// config/vite.base.ts
import type { UserConfig } from "vite"
import { resolve } from "path"

const baseConfig: UserConfig = {
  resolve: {
    alias: {
      "@": resolve(__dirname, "../src"),
    },
  },
}

export default baseConfig

Тип UserConfig поможет вам избежать опечаток в названиях полей и подскажет возможные опции.


Конфигурация Vite — это гибкий инструмент, который можно подстроить под практически любой фронтенд-проект: от маленького SPA до сложного монорепозитория или библиотеки. Вы можете управлять корнем проекта, путями, dev-сервером, сборкой, CSS, плагинами и даже поведением на разных окружениях.

Как только вы начнете осознанно использовать vite.config, устраивать деплой под разные среды и оптимизировать сборку, Vite перестанет быть "черной коробкой" и станет предсказуемым инструментом в вашей инфраструктуре.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как сделать разные настройки base для dev и prod без ручного изменения конфига

Используйте конфигурацию как функцию и режимы:

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig(({ mode }) => {
  // Здесь мы меняем base в зависимости от режима
  const isProd = mode === "production"

  return {
    base: isProd ? "/my-app/" : "/",
  }
})

Далее:

# Для dev
vite

# Для prod
vite build --mode production

Vite сам подставит нужное значение base.


Как использовать разные .env файлы для dev, staging и prod

Создайте файлы:

  • .env.development
  • .env.staging
  • .env.production

Запускайте с указанием режима:

# Dev
vite --mode development

# Staging
vite --mode staging

# Prod build
vite build --mode production

В конфиге вы сможете ориентироваться по mode, а в коде использовать import.meta.env, куда попадут переменные из соответствующих .env файлов.


Как настроить alias на общую папку в монорепозитории (pnpm workspace или Yarn workspaces)

Используйте абсолютный путь и, при необходимости, укажите preserveSymlinks:

// vite.config.ts
import { defineConfig } from "vite"
import { resolve } from "path"

export default defineConfig({
  resolve: {
    alias: {
      "@shared": resolve(__dirname, "../shared/src"),
    },
    // Здесь мы сохраняем симлинки, если это необходимо
    preserveSymlinks: true,
  },
})

Теперь вы можете импортировать общий код:

// Здесь мы используем общий код из монорепозитория
import { utils } from "@shared/utils"

Как выключить HMR для определенных файлов или модулей

Используйте хук handleHotUpdate в плагине:

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  plugins: [
    {
      name: "disable-hmr-for-json",
      // Здесь мы перехватываем обновления файлов
      handleHotUpdate({ file, server }) {
        if (file.endsWith(".json")) {
          // Перезапускаем полную перезагрузку страницы
          server.ws.send({ type: "full-reload" })
          // Возвращаем пустой массив, чтобы отключить HMR для этого файла
          return []
        }
      },
    },
  ],
})

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


Как настроить кэширование статических файлов (cache control) на preview или prod

Vite сам по себе не управляет HTTP-заголовками на продакшне, этим занимается сервер (Nginx, CDN и т. д.). Но на preview-сервере можно прокинуть нужные заголовки через middleware:

// vite.config.ts
import { defineConfig } from "vite"

export default defineConfig({
  preview: {
    // Здесь мы добавляем middleware, который выставляет заголовки
    configurePreviewServer(server) {
      server.middlewares.use((req, res, next) => {
        if (req.url && req.url.startsWith("/assets/")) {
          // Устанавливаем заголовок кэширования для ассетов
          res.setHeader("Cache-Control", "public, max-age=31536000, immutable")
        }
        next()
      })
    },
  },
})

На боевом сервере аналогичные заголовки нужно настроить в конфиге вашего веб-сервера или CDN.

Конфигурация Webpack - webpack config шаг за шагомСтрелочка вправо

Все гайды по Feature-sliced_design

Открыть базу знаний

Отправить комментарий