Vite

Vite представляет собой современный инструмент сборки фронтенд-приложений, ориентированный на скорость разработки и минимизацию времени холодного старта. Его ключевая особенность заключается в отказе от традиционного бандлинга на этапе разработки: исходные модули подаются в браузер как ES-модули, а сборка выполняется только для production.

Основные принципы архитектуры:

  • использование нативной поддержки ES Modules в браузере
  • предварительная оптимизация зависимостей через esbuild
  • разделение dev-сервера и production-сборки
  • ленивое преобразование модулей по запросу

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


Dev-сервер и модель исполнения модулей

Vite dev-сервер работает поверх нативных ES Modules. Каждый импорт рассматривается как отдельный HTTP-запрос, который сервер перехватывает и трансформирует при необходимости.

Механизм работы:

  • браузер запрашивает entry-файл
  • Vite анализирует import-граф
  • каждый модуль обрабатывается отдельно
  • трансформация выполняется только для затронутых файлов

Это принципиально отличается от webpack-подхода, где строится единый граф и создаётся один или несколько бандлов.

Преобразование модулей

Vite поддерживает трансформации:

  • TypeScript → JavaScript
  • JSX / TSX → JavaScript
  • CSS / SCSS / Less → встроенные стили
  • JSON / assets → модули

Трансформация выполняется через быстрые инструменты (в первую очередь esbuild), что снижает задержки до минимума.


Pre-bundling зависимостей

Одна из ключевых оптимизаций Vite — предварительное бандлирование зависимостей.

Причины:

  • npm-пакеты часто поставляются в формате CommonJS или с множественными ESM-файлами
  • количество отдельных импортов может быть слишком большим

Решение:

  • Vite использует esbuild для объединения зависимостей
  • создаётся кэшированный оптимизированный слой в node_modules/.vite

Преимущества:

  • уменьшение количества HTTP-запросов
  • ускорение холодного старта
  • нормализация форматов модулей

Hot Module Replacement (HMR)

HMR в Vite реализован через точечное обновление модулей без перезагрузки страницы.

Механика:

  • Vite отслеживает изменения файлов через file watcher
  • обновлённый модуль отправляется через WebSocket
  • браузер заменяет только изменённую часть графа

Особенности:

  • сохранение состояния приложения
  • мгновенное обновление UI
  • поддержка реактивных фреймворков (Vue, React, Svelte)

HMR интегрирован на уровне модульной системы, а не сборки, что делает его более точным и быстрым.


Конфигурация проекта

Основной конфигурационный файл — vite.config.js или vite.config.ts.

Пример базовой конфигурации:

import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    port: 3000,
    open: true
  },
  build: {
    outDir: 'dist',
    sourcemap: true
  }
})

Основные секции конфигурации

server

  • настройки dev-сервера
  • прокси API
  • порт и хост

build

  • параметры production-сборки
  • настройка Rollup
  • минификация

resolve

  • алиасы импортов
  • расширения файлов
resolve: {
  alias: {
    '@': '/src'
  }
}

Плагинная система

Vite использует плагинную систему, совместимую с Rollup, но расширенную под dev-сервер.

Плагин может:

  • перехватывать загрузку модулей
  • трансформировать код
  • добавлять HMR-логики
  • изменять конфигурацию сборки

Пример простого плагина:

export default function myPlugin() {
  return {
    name: 'my-plugin',
    transform(code, id) {
      if (id.endsWith('.js')) {
        return code.replace(/console.log/g, '')
      }
    }
  }
}

Этапы работы плагинов

  • resolveId — разрешение импортов
  • load — загрузка содержимого модуля
  • transform — трансформация кода
  • configureServer — настройка dev-сервера

Production-сборка

Для production Vite использует Rollup как базовый bundler.

Процесс сборки:

  • анализ dependency graph
  • tree-shaking
  • код-сплиттинг
  • минификация
  • генерация статических файлов

Особенности:

  • автоматическое разделение чанков
  • оптимизация динамических импортов
  • поддержка legacy-браузеров через отдельные сборки

Code Splitting

Vite активно использует динамические импорты:

const module = await import('./module.js')

Это приводит к:

  • созданию отдельного чанка
  • загрузке только при необходимости
  • снижению первоначального веса приложения

Работа с CSS

Vite рассматривает CSS как часть графа модулей.

Поддерживается:

  • обычный CSS
  • CSS Modules
  • препроцессоры (Sass, Less, Stylus)
  • PostCSS

Пример CSS Modules:

.title {
  color: blue;
}
import styles from './style.module.css'

element.className = styles.title

Обработка статических ресурсов

Ассеты обрабатываются как модули:

  • изображения
  • шрифты
  • медиафайлы

Пример:

import logo from './logo.png'

Vite возвращает URL к оптимизированному ресурсу.


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

Vite использует .env файлы.

Правила:

  • переменные должны начинаться с VITE_
  • доступны через import.meta.env

Пример:

VITE_API_URL=https://api.example.com

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

const url = import.meta.env.VITE_API_URL

SSR (Server-Side Rendering)

Vite поддерживает SSR через отдельный режим.

Особенности:

  • разделение server/client окружений
  • возможность использовать один и тот же код
  • предварительный рендеринг HTML

Основные сценарии:

  • Nuxt-like приложения
  • React SSR
  • Vue SSR

Оптимизация производительности

Vite достигает высокой скорости за счёт комбинации технологий:

  • esbuild для трансформации
  • native ESM вместо бандлов
  • кеширование pre-bundled зависимостей
  • ленивые трансформации
  • минимизация работы в dev-режиме

Ключевая метрика — время запуска dev-сервера, которое не зависит от размера проекта.


Сравнение с традиционными сборщиками

Webpack

  • полный бандлинг проекта в dev
  • длительный cold start
  • сложная конфигурация

Vite

  • отсутствие бандлинга в dev
  • мгновенный старт
  • простая конфигурация по умолчанию
  • разделение dev/build процессов

Типичная структура проекта

project/
  src/
    main.js
    components/
  public/
  vite.config.js
  index.html

Особенность Vite — index.html является частью графа сборки и точкой входа.