Использование vite-plugin-checker

vite-plugin-checker — плагин для экосистемы Vite, предназначенный для запуска дополнительных проверок во время разработки и сборки проекта. Основная задача плагина — вынести тяжёлые процессы анализа кода из основной цепочки трансформации модулей и запускать их параллельно.

Плагин особенно полезен в проектах с:

  • TypeScript;
  • Vue;
  • ESLint;
  • Stylelint;
  • Biome;
  • oxlint;
  • большими монорепозиториями;
  • интенсивным использованием HMR.

По умолчанию Vite выполняет только транспиляцию TypeScript через esbuild и не производит полноценную проверку типов. Аналогичная ситуация наблюдается и с линтингом: Vite не запускает ESLint автоматически. vite-plugin-checker закрывает этот пробел.


Установка плагина

Установка через npm:

npm install vite-plugin-checker --save-dev

Установка через pnpm:

pnpm add vite-plugin-checker -D

Установка через yarn:

yarn add vite-plugin-checker -D

Подключение к Vite

Базовая конфигурация:

// vite.config.ts
import { defineConfig } from 'vite'
import checker from 'vite-plugin-checker'

export default defineConfig({
  plugins: [
    checker({
      typescript: true
    })
  ]
})

После подключения плагин запускает отдельный worker-процесс для проверки TypeScript.


Проверка TypeScript

Проблема встроенной поддержки TypeScript в Vite

Vite использует esbuild для максимально быстрой трансформации TypeScript:

const user: string = 123

Несмотря на ошибку типов, Vite успешно выполнит транспиляцию:

const user = 123

Ошибки типов при этом проигнорируются.

Полноценная проверка появляется только при запуске:

tsc --noEmit

Именно этот процесс автоматизирует vite-plugin-checker.


Базовая настройка TypeScript checker

checker({
  typescript: true
})

Эквивалентно:

checker({
  typescript: {
    tsconfigPath: 'tsconfig.json'
  }
})

Указание собственного tsconfig

Во многих проектах используется несколько конфигураций TypeScript:

tsconfig.json
tsconfig.app.json
tsconfig.node.json

Плагин позволяет выбрать нужный файл:

checker({
  typescript: {
    tsconfigPath: './tsconfig.app.json'
  }
})

Проверка нескольких конфигураций

В монорепозиториях часто применяется project references:

{
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/ui" }
  ]
}

В этом случае checker использует основной tsconfig:

checker({
  typescript: {
    tsconfigPath: './tsconfig.json'
  }
})

Внутри TypeScript автоматически проверяются все references.


Overlay-ошибки в браузере

Одной из ключевых возможностей плагина является browser overlay.

При возникновении ошибки поверх страницы отображается специальное окно:

const total: number = '100'

На экране появляется сообщение:

Type 'string' is not assignable to type 'number'

Это существенно ускоряет разработку, поскольку ошибка сразу видна в браузере без переключения в терминал.


Отключение overlay

Иногда overlay мешает работе интерфейса, особенно при демонстрации проекта.

Отключение:

checker({
  typescript: true,
  overlay: false
})

Либо настройка объекта:

checker({
  overlay: {
    initialIsOpen: false
  }
})

Проверка ESLint

Подключение ESLint checker

checker({
  eslint: {
    lintCommand: 'eslint "./src/**/*.{ts,tsx}"'
  }
})

Плагин запускает указанный shell-командой линтер в отдельном процессе.


Почему lintCommand обязателен

vite-plugin-checker не генерирует конфигурацию ESLint автоматически. Причины:

  • разные версии ESLint;
  • legacy config и flat config;
  • разные glob-маски;
  • монорепозитории;
  • кастомные parser options.

Поэтому разработчик полностью контролирует команду запуска.


Проверка React-проекта

Типичная конфигурация:

checker({
  typescript: true,
  eslint: {
    lintCommand: 'eslint "./src/**/*.{ts,tsx}"'
  }
})

Проверка Vue-проекта

Для Vue используется vue-tsc.

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

checker({
  vueTsc: true
})

Почему обычный tsc недостаточен для Vue

Single File Components содержат:

<script setup lang="ts">
const count: number = '10'
</script>

Обычный TypeScript-компилятор не анализирует .vue-файлы.

vue-tsc использует инфраструктуру Vue compiler и понимает:

  • template section;
  • script setup;
  • props;
  • emits;
  • refs;
  • slots.

Одновременная проверка Vue и ESLint

checker({
  vueTsc: true,

  eslint: {
    lintCommand: 'eslint "./src/**/*.{ts,vue}"'
  }
})

Проверка Stylelint

Подключение:

checker({
  stylelint: {
    lintCommand: 'stylelint "./src/**/*.{css,scss}"'
  }
})

Проверка SCSS

checker({
  stylelint: {
    lintCommand: 'stylelint "./src/**/*.{scss}"'
  }
})

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

Современные проекты всё чаще переходят на Biome вместо ESLint + Prettier.

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

checker({
  biome: {
    command: 'biome check ./src'
  }
})

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

Высокопроизводительный линтер на Rust:

checker({
  oxlint: {
    command: 'oxlint ./src'
  }
})

Параллельная работа нескольких checker-процессов

Плагин способен запускать сразу несколько независимых worker-процессов:

checker({
  typescript: true,

  eslint: {
    lintCommand: 'eslint "./src/**/*.{ts,tsx}"'
  },

  stylelint: {
    lintCommand: 'stylelint "./src/**/*.{css,scss}"'
  }
})

Каждая проверка выполняется независимо.


Архитектура worker-процессов

Ключевая особенность vite-plugin-checker — вынесение анализа в отдельные потоки.

Без checker:

Vite main thread
 ├─ transform
 ├─ HMR
 └─ bundle

С checker:

Vite main thread
 ├─ transform
 ├─ HMR
 └─ bundle

Checker worker
 ├─ TypeScript
 ├─ ESLint
 └─ Stylelint

Благодаря этому HMR остаётся быстрым даже при тяжёлых проверках.


Проверка только во время build

Иногда проверки не нужны в dev-режиме.

Настройка:

checker({
  enableBuild: true,
  typescript: true
})

Отключение в production

Можно включить checker только для разработки:

checker({
  typescript: process.env.NODE_ENV === 'development'
})

Использование с create-vite

Многие шаблоны create-vite уже содержат TypeScript:

npm create vite@latest

Но полноценной проверки типов там нет.

После подключения checker:

checker({
  typescript: true
})

проект начинает вести себя ближе к полноценному IDE-анализу.


Интеграция с React

Типичная конфигурация React + TypeScript:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import checker from 'vite-plugin-checker'

export default defineConfig({
  plugins: [
    react(),

    checker({
      typescript: true,

      eslint: {
        lintCommand: 'eslint "./src/**/*.{ts,tsx}"'
      }
    })
  ]
})

Интеграция с Vue

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import checker from 'vite-plugin-checker'

export default defineConfig({
  plugins: [
    vue(),

    checker({
      vueTsc: true
    })
  ]
})

Интеграция с Svelte

checker({
  typescript: true
})

Для Svelte полноценная проверка обычно выносится в отдельный svelte-check.


Интеграция с Solid

checker({
  typescript: true
})

Проверка JavaScript-проектов

Плагин полезен даже без TypeScript:

checker({
  eslint: {
    lintCommand: 'eslint "./src/**/*.{js,jsx}"'
  }
})

Использование в монорепозиториях

Структура:

apps/
packages/

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

checker({
  typescript: {
    tsconfigPath: './tsconfig.json'
  },

  eslint: {
    lintCommand: 'eslint "./apps/**/*.{ts,tsx}"'
  }
})

Производительность

Почему checker не встроен в Vite по умолчанию

Основная философия Vite:

  • минимальная задержка HMR;
  • мгновенный cold start;
  • быстрые преобразования.

Полноценная проверка типов значительно замедляет dev-server.

Поэтому архитектура разделена:

Задача Инструмент
Трансформация esbuild
Проверка типов TypeScript
Линтинг ESLint
Оркестрация vite-plugin-checker

Влияние на HMR

При правильно настроенном checker:

  • обновление модулей остаётся быстрым;
  • проверки выполняются параллельно;
  • блокировки dev server практически отсутствуют.

Однако крупные TypeScript-монорепозитории всё равно могут создавать нагрузку на CPU.


Ограничение области проверки

Для ускорения рекомендуется уменьшать glob-маски:

Плохо:

eslint: {
  lintCommand: 'eslint "./**/*"'
}

Лучше:

eslint: {
  lintCommand: 'eslint "./src/**/*.{ts,tsx}"'
}

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

Для ESLint:

eslint: {
  lintCommand: 'eslint "./src/**/*.{ts,tsx}" --cache'
}

Это значительно ускоряет повторные проверки.


Проверка только изменённых файлов

Некоторые линтеры поддерживают инкрементальный режим.

Например:

eslint --cache

или:

biome check --changed

Типичные ошибки конфигурации

Ошибка tsconfigPath

Cannot find tsconfig.json

Причина:

tsconfigPath: './configs/tsconfig.app.json'

при неверном пути.


Ошибка отсутствия ESLint

Failed to run lint command

Причины:

  • eslint не установлен;
  • неверный lintCommand;
  • конфликт shell-синтаксиса;
  • неправильные кавычки glob-маски.

Проблемы Windows shell

Иногда возникают ошибки с glob:

lintCommand: 'eslint "./src/**/*.{ts,tsx}"'

Для Windows PowerShell может потребоваться:

lintCommand: 'eslint . --ext .ts,.tsx'

Конфликт overlay с другими плагинами

Некоторые плагины также используют browser overlay:

  • React Refresh;
  • runtime error overlay;
  • framework-specific overlays.

Возможны визуальные конфликты.

Решение:

overlay: false

Использование в CI/CD

Несмотря на dev-ориентированность, checker иногда применяется и в CI:

vite build

Если включён:

enableBuild: true

то ошибки типов остановят сборку.


Разделение dev и CI-проверок

Часто используется схема:

Dev

checker({
  typescript: true
})

CI

tsc --noEmit
eslint .

Такой подход даёт:

  • быстрый локальный feedback;
  • строгий контроль в pipeline;
  • независимость CI от Vite.

Внутренний механизм работы

Плагин использует:

  • child_process;
  • worker threads;
  • watcher-инфраструктуру;
  • IPC-обмен между процессами.

Изменение файла:

File changed
   ↓
Vite watcher
   ↓
checker worker
   ↓
TypeScript / ESLint
   ↓
overlay + terminal output

Когда vite-plugin-checker особенно полезен

Наиболее эффективен плагин в проектах:

  • с TypeScript;
  • с большим количеством компонентов;
  • с активным ESLint;
  • с Vue SFC;
  • с монорепозиториями;
  • с интенсивным HMR;
  • с командной разработкой.

Когда плагин может быть избыточным

В небольших проектах checker иногда не нужен:

  • маленькие pet-проекты;
  • чистый JavaScript без линтинга;
  • минимальные SPA;
  • проекты без TypeScript;
  • среды с ограниченными ресурсами CPU/RAM.

В таких случаях достаточно:

tsc --noEmit

или отдельных npm scripts.