Связка Vite и Vue 3 строится вокруг концепции ESM-first (native ES Modules) и разделения режимов разработки и сборки. В основе лежит то, что Vite не бандлит приложение в режиме dev, а отдает модули по требованию через dev-сервер, а сборка выполняется Rollup-подобным пайплайном в production.
Для Vue 3 ключевым элементом интеграции выступает официальный плагин
@vitejs/plugin-vue, обеспечивающий:
<script setup><style scoped>Без этого плагина Vite воспринимает .vue файлы как
обычный текстовый импорт и не способен интерпретировать их
структуру.
@vitejs/plugin-vue в сборочном процессеПлагин работает на уровне трансформации модулей Vite. Каждый
.vue файл проходит через несколько стадий:
Разбор SFC в AST (Abstract Syntax Tree)
Разделение на блоки:
<template><script> / <script setup><style>Компиляция шаблона в render-функцию
Преобразование script блока в ES module
Инъекция HMR-метаданных
Обработка CSS scoping и постобработка
В результате один .vue файл превращается в несколько
виртуальных модулей, связанных между собой через импортную графовую
структуру Vite.
Плагин подключается в конфигурации Vite через
plugins:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()]
})
На этом уровне Vite начинает распознавать .vue как
полноценные модули и передает их в пайплайн плагина.
Дополнительно используется peer-зависимость
vue/compiler-sfc, которая должна соответствовать версии Vue
3.
Каждый Vue SFC разбивается на логические части:
Пример структуры:
<template>
<div>{{ message }}</div>
</template>
<script setup>
const message = 'Hello'
</script>
<style scoped>
div {
color: red;
}
</style>
Плагин превращает это в набор виртуальных импортов:
Component.vue?vue&type=templateComponent.vue?vue&type=scriptComponent.vue?vue&type=style&index=0Vue 3 использует компиляцию шаблонов в render-функции Jav * aScript:
import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_ctx.message)))
}
@vitejs/plugin-vue передает template в Vue compiler,
который:
v-if, v-for)Оптимизация static hoisting особенно важна для производительности, так как снижает количество операций diff при рендеринге.
<script setup>Одним из ключевых элементов Vue 3 является script setup,
который обрабатывается плагином на этапе трансформации.
Исходный код:
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
Трансформация:
export defaultРезультат примерно эквивалентен:
export default {
setup() {
const count = ref(0)
return { count }
}
}
Но фактически используется более низкоуровневая оптимизация без явного объекта.
При использовании:
<style scoped>
.button {
color: blue;
}
</style>
плагин:
Пример трансформации:
.button[data-v-123abc] {
color: blue;
}
И в DOM:
<button data-v-123abc>Click</button>
При использовании:
<style module>
.title {
color: green;
}
</style>
плагин генерирует объект:
export default {
title: '_title_1a2b3c'
}
И предоставляет его в компонент через $style.
HMR в связке Vite + Vue 3 работает на уровне granular updates:
Плагин отправляет HMR-сообщения через WebSocket:
import.meta.hot.accept()
Vue runtime получает обновление и заменяет только измененную часть компонента, сохраняя состояние, если это возможно.
Vite строит dependency graph на основе ES imports:
import MyComponent from './MyComponent.vue'
Плагин превращает .vue файл в виртуальный модуль с
несколькими подмодулями:
Это позволяет Vite:
В production режиме Vite использует Rollup-подобную сборку:
@vitejs/plugin-vue участвует в следующих этапах:
Особенно важна работа с static nodes:
<div>
<h1>Static title</h1>
</div>
Такие узлы hoistятся и не пересоздаются при каждом рендере.
Плагин поддерживает TypeScript внутри
<script lang="ts">:
<script setup lang="ts">
interface User {
name: string
}
const user: User = { name: 'Alex' }
</script>
Обработка включает:
При использовании SSR плагин обеспечивает:
Основная задача — сохранить идентичность DOM между сервером и клиентом, используя одинаковые render-функции.
@vitejs/plugin-vue может быть расширен через
дополнительные плагины:
@vitejs/plugin-vue-jsx)Пайплайн выглядит как цепочка:
Некоторые важные нюансы:
.vue файлы всегда компилируются, даже при отсутствии
template@vitejs/plugin-vue фактически является мостом между
декларативной моделью Vue SFC и ESM-ориентированной архитектурой
Vite.
Он выполняет не просто трансформацию файлов, а полноценную реконструкцию компонентов в виде графа модулей, где каждая часть SFC становится независимым, оптимизируемым узлом сборки.
Это позволяет Vite сохранять минимальное время dev startup, а Vue 3 — поддерживать высокую реактивность и предсказуемость рендера без дополнительного runtime overhead.