Плагин eslint-plugin-vue

eslint-plugin-vue

Плагин eslint-plugin-vue предназначен для статического анализа файлов Vue Single File Components (SFC) и JavaScript-кода, связанного с Vue-приложениями. Он расширяет возможности ESLint за пределы обычного JavaScript, добавляя понимание структуры шаблонов <template>, секций <script> и <style> внутри .vue файлов.

Ключевая задача заключается в обеспечении согласованности, читаемости и предсказуемости Vue-кода через набор специализированных правил, учитывающих особенности реактивности, директив, компонентов и шаблонного синтаксиса.

Архитектура работы плагина

Плагин строится вокруг двух основных компонентов:

  • Parser (vue-eslint-parser) обеспечивает разбор .vue файлов в AST, объединяющий JavaScript и template-часть.
  • Ruleset набор правил, разделённых по категориям: корректность, стиль, лучшие практики, безопасность.

AST, создаваемый парсером, содержит:

  • JavaScript AST для <script>
  • Template AST для <template>
  • связующие узлы, позволяющие сопоставлять выражения внутри шаблона с логикой компонента

Установка и базовая интеграция

Плагин используется совместно с ESLint и парсером Vue:

npm install -D eslint eslint-plugin-vue vue-eslint-parser

В типичной конфигурации ESLint подключение выглядит следующим образом:

module.exports = {
  parser: "vue-eslint-parser",
  parserOptions: {
    parser: "@babel/eslint-parser",
    ecmaVersion: "latest",
    sourceType: "module"
  },
  plugins: ["vue"],
  extends: [
    "plugin:vue/vue3-recommended"
  ]
};

Ключевой момент заключается в том, что именно vue-eslint-parser становится верхнеуровневым парсером, делегируя разбор JavaScript вложенному парсеру.

Поддержка Vue 2 и Vue 3

Плагин исторически поддерживает обе версии Vue, но правила и пресеты различаются:

  • Vue 2: plugin:vue/recommended
  • Vue 3: plugin:vue/vue3-recommended
  • строгие режимы: essential, strongly-recommended, recommended

Различия проявляются в обработке:

  • v-model (изменённая семантика во Vue 3)
  • multiple root nodes
  • script setup
  • Composition API

Flat Config и современная конфигурация ESLint

В Flat Config (ESLint 9+) интеграция становится более явной:

import vue from "eslint-plugin-vue";
import vueParser from "vue-eslint-parser";

export default [
  {
    files: ["**/*.vue"],
    languageOptions: {
      parser: vueParser,
      parserOptions: {
        parser: "@babel/eslint-parser",
        ecmaVersion: "latest",
        sourceType: "module"
      }
    },
    plugins: {
      vue
    },
    rules: {
      ...vue.configs["vue3-recommended"].rules
    }
  }
];

Особенность Flat Config — явное распределение конфигурации по файлам и отсутствие extends в классическом виде.

Категории правил

Правила плагина структурированы по смысловым группам.

Корректность шаблонов

Эта группа контролирует синтаксические ошибки Vue template:

  • корректность директив (v-if, v-for, v-bind)
  • отсутствие конфликтов между директивами
  • проверка выражений внутри интерполяций

Примеры правил:

  • vue/no-unused-vars
  • vue/no-template-shadow
  • vue/valid-v-for

Логика компонентов

Контроль архитектурных проблем:

  • дублирование свойств
  • неправильное использование props
  • некорректная работа с emits

Примеры:

  • vue/no-duplicate-attributes
  • vue/require-prop-types
  • vue/require-default-prop

Стиль шаблонов

Единообразие структуры:

  • отступы в template
  • порядок атрибутов
  • форматирование директив

Примеры:

  • vue/html-indent
  • vue/max-attributes-per-line
  • vue/first-attribute-linebreak

Безопасность и предсказуемость

Правила предотвращают потенциальные ошибки выполнения:

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

Примеры:

  • vue/valid-v-for
  • vue/no-side-effects-in-computed-properties

Работа с Vue SFC (Single File Components)

Файлы .vue разбиваются на блоки:

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  data() {
    return {
      message: "text"
    }
  }
}
</script>

Парсер преобразует это в единую структуру, где:

  • template анализируется отдельно
  • script обрабатывается как обычный JS
  • ошибки синхронизируются по строкам исходного файла

Особенность заключается в корректной маппинге строковых смещений между виртуальными AST и оригинальным файлом.

Script Setup и Composition API

Поддержка <script setup> требует расширенного анализа:

<script setup>
import { ref } from "vue"

const count = ref(0)
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>

Плагин анализирует:

  • неявные экспорты
  • макросы defineProps, defineEmits
  • реактивные переменные без явного return

Правила адаптируются под отсутствие export default.

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

В сочетании с @typescript-eslint/parser:

parser: "vue-eslint-parser",
parserOptions: {
  parser: "@typescript-eslint/parser"
}

Возможности:

  • проверка типов props
  • анализ интерфейсов компонентов
  • валидация emits

Ограничения:

  • сложные generics внутри template выражений не всегда полностью анализируются
  • часть type inference происходит вне ESLint слоя

Режимы рекомендаций и пресеты

Плагин предоставляет набор конфигураций:

  • essential — критические ошибки
  • recommended — баланс качества и гибкости
  • strongly-recommended — строгие правила
  • vue3-recommended — современный стандарт Vue 3

Каждый пресет представляет заранее определённый набор правил, включающих:

  • обязательные проверки
  • стилистические ограничения
  • best practices для экосистемы Vue

Правила работы с шаблонами

Template-часть имеет отдельный набор ограничений:

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

Пример проблемного кода:

<div>{{ items.filter(x => x.active).map(x => x.name) }}</div>

Такой код часто нарушает правило vue/no-template-shadow и усложняет отладку реактивности.

Интеграция с Vite и Nuxt

В современных сборках:

Vite

  • ESLint подключается как plugin
  • анализ происходит параллельно сборке

Nuxt 3

  • автоматическая интеграция через модуль ESLint
  • отдельная конфигурация для .vue и server-side частей

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

  • разделение client/server правил
  • разные окружения для SSR

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

Факторы влияния:

  • количество SFC файлов
  • сложность template AST
  • использование TypeScript
  • глубина Composition API

Оптимизации:

  • кэширование parser results
  • исключение node_modules
  • ограничение правил template linting при CI

Типичные классы ошибок

Ошибки шаблонов

  • отсутствие key в v-for
  • неправильное использование v-if и v-for одновременно

Ошибки компонентов

  • отсутствие props типов
  • конфликт имен props и data

Архитектурные проблемы

  • чрезмерная логика в template
  • отсутствие разделения computed properties

Расширение плагина

Возможности кастомизации:

  • создание собственных rules
  • расширение AST visitors
  • интеграция с корпоративными стилями

Структура кастомного правила:

module.exports = {
  meta: {
    type: "problem"
  },
  create(context) {
    return {
      "VExpressionContainer"(node) {
        // анализ выражений шаблона
      }
    }
  }
};

AST-события зависят от vue-eslint-parser и отличаются от стандартного ESLint.

Особенности анализа директив

Директивы Vue требуют отдельной обработки:

  • v-bind
  • v-model
  • v-on
  • кастомные директивы

Плагин проверяет:

  • корректность аргументов
  • допустимость выражений
  • отсутствие конфликтов атрибутов

Ограничения и пограничные случаи

  • динамические шаблоны ограниченно анализируются
  • сложные runtime-условия не всегда детектируются
  • часть ошибок проявляется только в runtime Vue
  • макросы Composition API требуют специальных парсеров

Связь с экосистемой линтинга

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

  • ESLint core
  • TypeScript ESLint
  • Prettier (через отключение конфликтующих правил)
  • Vetur / Volar (в IDE-слое)

Синхронизация между инструментами важна для избежания дублирующей диагностики.