Как создавать и использовать плагины в Vite
Создание пользовательских плагинов Vite позволяет расширить процесс сборки за пределы стандартной конфигурации — будь то преобразование пользовательских типов файлов, внедрение логики во время сборки или добавление middleware для сервера разработки. Если вы достигли пределов стандартной конфигурации Vite, создание собственного плагина — естественный следующий шаг.
Это руководство охватывает основные концепции: как работает Plugin API Vite, ключевые хуки жизненного цикла, которые вы будете использовать, и практические примеры для начала работы. Вы научитесь создавать, тестировать и публиковать плагины, которые решают реальные задачи в вашем рабочем процессе разработки.
Ключевые выводы
- Плагины Vite расширяют процессы разработки и production-сборки через хуки жизненного цикла
- Большинство плагинов Rollup работают в Vite, но функции dev-сервера требуют специфичных для Vite хуков
- Начните с простых преобразований, прежде чем переходить к продвинутым паттернам, таким как виртуальные модули
- Следуйте соглашениям об именовании и стандартам документации при публикации плагинов
Понимание плагинов Vite и их связи с Rollup
Плагины Vite — это JavaScript-объекты, которые подключаются к различным этапам процесса разработки и сборки. Они построены на основе системы плагинов Rollup с дополнительными хуками, специфичными для сервера разработки Vite.
Vite использует два разных инструмента сборки под капотом: esbuild обеспечивает молниеносно быстрый сервер разработки с нативными ES-модулями, в то время как Rollup обрабатывает production-бандлинг для оптимального вывода. Эта двойная архитектура означает, что ваши плагины могут нацеливаться на конкретные окружения с помощью опции apply:
function myPlugin(): Plugin {
return {
name: 'my-plugin',
apply: 'serve', // Only runs during development
// ... hooks
}
}
Большинство плагинов Rollup работают в Vite без модификаций. Однако, если вам нужна функциональность dev-сервера — например, добавление middleware или изменение HTML во время разработки — вам потребуются специфичные для Vite хуки.
Базовая структура плагина и конфигурация
Каждый плагин Vite должен иметь свойство name и как минимум одну функцию-хук:
import type { Plugin } from 'vite'
function myPlugin(options?: MyPluginOptions): Plugin {
return {
name: 'vite-plugin-example',
enforce: 'pre', // Optional: control plugin ordering
apply: 'build', // Optional: 'serve' | 'build' | undefined
// Hook functions go here
transform(code, id) {
if (id.endsWith('.custom')) {
return transformCustomFile(code)
}
}
}
}
Plugin API предоставляет TypeScript-определения для всех хуков и опций. Импортируйте тип Plugin из ‘vite’ для полной типобезопасности и автодополнения.
Основные хуки жизненного цикла в Plugin API
Различные хуки срабатывают на разных этапах процесса сборки. Вот наиболее часто используемые:
Хуки конфигурации
config: Изменение конфигурации Vite до её разрешенияconfigResolved: Доступ к финальной разрешённой конфигурации
Хуки преобразования
transform: Изменение исходного кода отдельных модулейload: Пользовательская логика загрузки для конкретных типов файловresolveId: Пользовательское разрешение модулей
{
name: 'transform-plugin',
transform(code, id) {
if (!id.includes('node_modules') && id.endsWith('.js')) {
return {
code: addCustomHeader(code),
map: null // Source map support
}
}
}
}
Хуки сервера и сборки
configureServer: Добавление пользовательского middleware к dev-серверуtransformIndexHtml: Изменение HTML-файловwriteBundle: Выполнение после записи бандла на диск
Каждый хук имеет специфичные типы возвращаемых значений и время выполнения. Хук transform запускается для каждого модуля, поэтому держите его быстрым. Используйте load для затратных операций над конкретными файлами.
Discover how at OpenReplay.com.
Создание вашего первого плагина Vite: практические примеры
Давайте создадим три практических плагина, демонстрирующих распространённые паттерны:
Пример 1: Модификация HTML
function htmlPlugin(): Plugin {
return {
name: 'html-modifier',
transformIndexHtml(html) {
return html.replace(
'</head>',
'<script>console.log("Injected!")</script></head>'
)
}
}
}
Пример 2: Middleware для dev-сервера
function analyticsPlugin(): Plugin {
return {
name: 'request-analytics',
configureServer(server) {
server.middlewares.use((req, res, next) => {
console.log(`${req.method} ${req.url}`)
next()
})
}
}
}
Пример 3: Генерация файлов во время сборки
import path from 'path'
import fs from 'fs'
import type { Plugin, ResolvedConfig } from 'vite'
function generateManifest(): Plugin {
let config: ResolvedConfig
return {
name: 'generate-manifest',
configResolved(resolvedConfig) {
config = resolvedConfig
},
writeBundle() {
const manifestPath = path.join(config.build.outDir, 'manifest.json')
fs.writeFileSync(manifestPath, JSON.stringify({
timestamp: Date.now(),
version: process.env.npm_package_version
}))
}
}
}
Для отладки используйте console.log в ваших хуках для трассировки выполнения. Методы this.warn() и this.error() обеспечивают лучшую отчётность об ошибках, чем выброс исключений.
Продвинутые паттерны плагинов и лучшие практики
Виртуальные модули
Создание модулей, которые не существуют на диске:
const virtualModuleId = 'virtual:my-module'
const resolvedVirtualModuleId = '\0' + virtualModuleId
export function virtualPlugin(): Plugin {
return {
name: 'virtual-plugin',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export const msg = "from virtual module"`
}
}
}
}
Оптимизация производительности
Кэширование затратных преобразований:
const cache = new Map<string, string>()
function cachedTransform(): Plugin {
return {
name: 'cached-transform',
transform(code, id) {
if (cache.has(id)) return cache.get(id)
const result = expensiveOperation(code)
cache.set(id, result)
return result
}
}
}
Тестируйте ваши плагины Vite с помощью Vitest, используя API createServer для проверки поведения хуков в изоляции.
Публикация и распространение вашего плагина
Следуйте этим соглашениям при публикации:
- Назовите ваш пакет
vite-plugin-[name] - Включите
"vite-plugin"в ключевые слова package.json - Документируйте, почему он специфичен для Vite (если использует хуки только для Vite)
- Добавьте префиксы фреймворка, если специфичен для фреймворка:
vite-plugin-vue-[name]
Создайте понятный README с инструкциями по установке, примерами конфигурации и документацией API. Отправьте ваш плагин в awesome-vite, чтобы охватить сообщество.
Заключение
Создание пользовательских плагинов Vite даёт вам полный контроль над процессом сборки. Начните с простых преобразований, используя хуки вроде transform или transformIndexHtml, затем расширяйте до более сложных паттернов по мере необходимости. Plugin API мощный, но при этом доступный — большинству плагинов требуется всего несколько хуков для решения конкретных задач.
Для более глубокого изучения ознакомьтесь с официальной документацией по плагинам Vite и изучите популярные плагины в экосистеме. Ваша следующая оптимизация сборки или улучшение рабочего процесса может быть всего в одном плагине от вас.
Часто задаваемые вопросы
Да, большинство плагинов Rollup работают с Vite без модификаций. Однако плагины, которые полагаются на хук moduleParsed или требуют функциональности dev-сервера, нуждаются в адаптации для Vite. Проверьте документацию плагина на предмет заметок о совместимости с Vite.
Используйте операторы console.log в ваших хуках для трассировки потока выполнения. Методы this.warn() и this.error() обеспечивают лучшую отчётность об ошибках. Вы также можете использовать переменную окружения DEBUG с Vite для просмотра детальных логов.
Опция enforce контролирует порядок выполнения плагинов. Pre-плагины выполняются до основных плагинов Vite, post-плагины — после. Используйте pre для входных преобразований и post для модификаций вывода. Без enforce плагины выполняются в порядке их появления.
Рассмотрите публикацию, если ваш плагин решает проблему, с которой могут столкнуться другие, даже если она специализированная. Чётко документируйте его конкретный случай использования. Для действительно проектно-специфичных плагинов храните их локально или в приватном реестре.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.