Одной из ключевых причин высокой скорости работы Vite является использование esbuild в режиме разработки. Вместо классической полной сборки проекта Vite применяет гибридную архитектуру, в которой браузер получает нативные ES-модули напрямую, а esbuild выполняет наиболее ресурсоёмкие задачи предварительной обработки.
Такая модель принципиально отличается от архитектуры старых bundler-систем, где любое изменение файла требовало перестройки значительной части графа зависимостей.
Основная идея Vite:
В этой архитектуре esbuild выполняет роль сверхбыстрого трансформера и препроцессора модулей.
Большинство JavaScript-инструментов долгое время строились вокруг экосистемы Node.js и интерпретируемого JavaScript-кода. Это создавало несколько проблем:
esbuild написан на языке Go и компилируется в нативный бинарный файл. Благодаря этому достигается очень высокая производительность.
Ключевые преимущества esbuild:
| Возможность | Практический эффект |
|---|---|
| Нативная реализация | Высокая скорость выполнения |
| Параллельная обработка | Эффективная загрузка всех ядер CPU |
| Быстрый парсинг AST | Минимальные задержки трансформации |
| Поддержка TypeScript | Компиляция без tsc |
| Поддержка JSX/TSX | Быстрая работа React-проектов |
| Минификация | Ускоренная production-сборка |
| Tree Shaking | Исключение неиспользуемого кода |
В режиме разработки Vite использует esbuild прежде всего как:
Современные браузеры поддерживают ES Modules:
<script type="module" src="/src/main.js"></script>
Однако при прямой загрузке зависимостей из node_modules
возникают проблемы:
Многие пакеты опубликованы в формате CommonJS:
const lodash = require('lodash')
module.exports = lodash
Браузер не способен напрямую выполнить такой код через ES Modules.
Некоторые библиотеки состоят из сотен модулей.
Например:
import { debounce } from 'lodash-es'
Без оптимизации браузер может инициировать десятки или сотни HTTP-запросов.
Если каждый модуль обрабатывается на лету без кеширования, старт dev-сервера становится медленным.
При запуске dev-сервера Vite анализирует зависимости проекта:
vite
После этого esbuild выполняет предварительную оптимизацию зависимостей.
Основные этапы:
node_modules.Одним из важнейших механизмов Vite является dependency pre-bundling.
Пример:
import React from 'react'
import ReactDOM from 'react-dom'
Vite обнаруживает:
После этого esbuild создаёт оптимизированные ESM-версии.
Результат помещается в:
node_modules/.vite
Пример содержимого:
node_modules/.vite/deps/
Там находятся заранее обработанные зависимости:
react.js
react-dom.js
chunk-XXXXX.js
Исходный код:
const lib = require('./lib')
module.exports = lib
После обработки:
import lib from './lib.js'
export default lib
Это позволяет браузеру корректно загружать зависимости как ES-модули.
Библиотеки часто имеют глубокий граф импортов:
lodash/
debounce.js
throttle.js
clone.js
merge.js
esbuild может объединить множество внутренних модулей в один оптимизированный файл.
Это уменьшает:
esbuild умеет выполнять tree shaking:
import { debounce } from 'lodash-es'
Если используется только debounce, остальной код может
быть исключён.
Скорость — главный фактор, определивший архитектуру Vite.
Типичные показатели:
| Инструмент | Скорость трансформации |
|---|---|
| Babel | Медленно |
| TypeScript Compiler | Средне |
| webpack loaders | Средне/медленно |
| esbuild | Очень быстро |
На крупных проектах разница может измеряться десятками секунд.
Vite не запускает TypeScript Compiler (tsc) для обычной
трансформации файлов во время разработки.
Вместо этого используется esbuild.
Файл:
const message: string = 'Hello'
esbuild удаляет типы:
const message = 'Hello'
Это происходит почти мгновенно.
Важно понимать различие:
| Задача | Выполняет esbuild |
|---|---|
| Удаление типов | Да |
| Трансформация TS → JS | Да |
| Type Checking | Нет |
Проверка типов требует полного анализа проекта и значительно замедляет сборку.
Поэтому Vite разделяет процессы:
tsc отвечает за проверку типов.Обычно проверка запускается отдельно:
tsc --noEmit
Для React-проектов esbuild компилирует JSX и TSX.
Исходный код:
function App() {
return <h1>Hello</h1>
}
После трансформации:
function App() {
return React.createElement("h1", null, "Hello")
}
Обработка происходит очень быстро даже в крупных React-приложениях.
Hot Module Replacement — один из важнейших элементов Vite.
Когда изменяется файл:
src/components/Button.jsx
Vite:
esbuild здесь играет роль сверхбыстрого трансформера.
Благодаря этому обновления интерфейса происходят практически мгновенно.
Традиционная схема:
Source Files
↓
Full Bundle Rebuild
↓
HMR Update
Даже небольшое изменение может запускать сложную перестройку графа модулей.
Современная схема:
Changed Module
↓
Fast Transform via esbuild
↓
Native ESM Delivery
Полная сборка не требуется.
После первого запуска Vite сохраняет результаты работы esbuild.
Каталог:
node_modules/.vite
Повторный запуск dev-сервера использует кеш.
Это существенно ускоряет startup time.
Vite повторно запускает pre-bundling при:
Например:
npm install axios
После этого Vite снова оптимизирует зависимости через esbuild.
Поведение dependency pre-bundling настраивается через
optimizeDeps.
Пример:
export default {
optimizeDeps: {
include: ['some-large-lib']
}
}
Принудительно включает зависимость в pre-bundling.
Полезно для:
Исключает пакет из оптимизации:
export default {
optimizeDeps: {
exclude: ['legacy-lib']
}
}
Статический импорт:
import utils from './utils'
Анализируется легко.
Но динамический импорт:
import(`./modules/${name}.js`)
Нельзя полностью предсказать заранее.
В таких случаях pre-bundling может работать ограниченно.
Несмотря на огромную скорость, esbuild имеет некоторые ограничения.
esbuild не заменяет TypeScript Compiler.
Babel предоставляет более гибкую экосистему трансформаций.
Особенно:
Во время production-сборки Vite использует Rollup.
Причины:
| Возможность | Rollup | esbuild |
|---|---|---|
| Глубокий tree shaking | Да | Ограниченно |
| Экосистема плагинов | Очень развитая | Ограниченная |
| Тонкая оптимизация чанков | Да | Частично |
| Максимальная скорость | Нет | Да |
Архитектура Vite сочетает преимущества обоих инструментов:
Упрощённая схема:
Browser
↓
Vite Dev Server
↓
esbuild Transform
↓
Optimized ESM Modules
При изменении файла:
File Change
↓
esbuild Re-transform
↓
HMR Update
↓
Browser Patch
Во время разработки Vite не создаёт bundle целиком.
При запросе:
/src/main.js
Vite:
Это называется on-demand transformation.
Классические bundler-системы сначала строят полный dependency graph.
Vite работает иначе:
Благодаря esbuild даже крупные проекты стартуют за секунды.
Многие плагины Vite используют esbuild API напрямую.
Например:
Пример конфигурации:
export default {
esbuild: {
jsxFactory: 'h',
jsxFragment: 'Fragment'
}
}
Во время разработки esbuild может генерировать source maps.
Это позволяет:
Архитектура Vite строится вокруг принципа разделения ответственности:
| Инструмент | Роль |
|---|---|
| Browser ESM | Загрузка модулей |
| Vite Dev Server | Оркестрация |
| esbuild | Быстрые трансформации |
| Rollup | Production bundling |
| TypeScript Compiler | Проверка типов |
Такой подход обеспечивает: