Парсер vue-eslint-parser

В контексте Vue Single File Components (SFC) стандартный парсер JavaScript, используемый в ESLint, оказывается недостаточным, поскольку структура .vue файлов включает не только JavaScript, но и шаблонную часть, стили и специальные директивы фреймворка. Для корректного анализа таких файлов применяется специализированный парсер vue-eslint-parser, который расширяет возможности стандартного анализа и обеспечивает работу ESLint с Vue-специфичной структурой.

Основная задача данного парсера заключается в преобразовании .vue файла в синтаксическое дерево (AST), пригодное для дальнейшего анализа правилами ESLint, сохраняя при этом совместимость с ESTree-форматом для JavaScript-кода и добавляя дополнительные узлы для template-части.


Архитектура обработки Vue Single File Component

Vue SFC состоит из трёх основных секций:

  • <template> — декларативный шаблон
  • <script> — логика компонента
  • <style> — стилизация

Парсер vue-eslint-parser разделяет обработку на несколько этапов:

  1. Разбиение SFC на блоки
  2. Парсинг <script> с использованием подключённого JS/TS парсера
  3. Построение отдельного AST для <template>
  4. Объединение деревьев в единый Vue AST

Ключевая особенность заключается в том, что итоговое дерево не является чистым JavaScript AST, а представляет собой гибридную структуру, где template и script сосуществуют в единой модели анализа.


Взаимодействие с базовым JavaScript-парсером

vue-eslint-parser не заменяет полностью парсинг JavaScript-кода. Вместо этого он делегирует обработку <script> части другому парсеру, чаще всего:

  • espree (стандартный парсер ESLint)
  • @babel/eslint-parser
  • @typescript-eslint/parser

Такой подход позволяет сохранять совместимость с современными возможностями языка, включая TypeScript, JSX и экспериментальные предложения ECMAScript.

Передача управления выглядит следующим образом:

  • Vue парсер выделяет содержимое <script>
  • передаёт его в указанный parser
  • получает обратно ESTree AST
  • интегрирует его в общий Vue AST

Конфигурация парсера в ESLint

Использование vue-eslint-parser задаётся через конфигурацию ESLint:

module.exports = {
  parser: "vue-eslint-parser",
  parserOptions: {
    parser: "@babel/eslint-parser",
    ecmaVersion: 2022,
    sourceType: "module",
    ecmaFeatures: {
      jsx: false
    }
  }
};

Параметр parserOptions.parser играет центральную роль, определяя, каким образом будет обрабатываться JavaScript внутри <script> блока.

Также поддерживаются дополнительные настройки:

  • parserOptions.ecmaVersion — версия ECMAScript
  • parserOptions.sourceType — модульная система (script/module)
  • parserOptions.extraFileExtensions — дополнительные расширения файлов

AST структура Vue файлов

AST, формируемый vue-eslint-parser, включает несколько уровней:

Корневой Vue AST

Корневой узел содержит метаданные файла и ссылки на дочерние блоки:

  • templateBody
  • scriptSetupElement (если используется <script setup>)
  • scripts
  • styles

Template AST

Template часть преобразуется в отдельное дерево, основанное на HTML-подобной структуре. Оно включает:

  • VElement (HTML элементы)
  • VText (текстовые узлы)
  • VExpressionContainer (выражения внутри {{ }})

Особенность заключается в том, что выражения внутри шаблона дополнительно анализируются как JavaScript-код.


Обработка выражений внутри шаблона

Vue template содержит интерполированные выражения:

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

Выражение message не является частью HTML AST напрямую. Оно передаётся в JavaScript-парсер для анализа идентификаторов, операторов и вызовов.

Это создаёт двойной уровень анализа:

  • HTML/Template уровень
  • JavaScript expression уровень

Такой механизм позволяет ESLint применять правила как к структуре шаблона, так и к логике выражений.


Script Setup и его особенности

Современный синтаксис <script setup> требует отдельной обработки. В рамках vue-eslint-parser он рассматривается как специализированный блок, в котором:

  • отсутствует явное экспортирование компонента
  • переменные автоматически становятся частью шаблона
  • используются макросы Vue (например, defineProps)

AST для script setup объединяется с template контекстом, что позволяет проверять:

  • использование не объявленных переменных в шаблоне
  • корректность пропсов
  • соблюдение реактивных ограничений Vue

Parser Services и расширенные возможности

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

Сервисы включают:

  • сопоставление узлов template и script
  • определение области видимости переменных
  • доступ к токенам Vue-шаблона
  • преобразование координат узлов (loc mapping)

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

  • получение информации о переменной в script
  • проверка её использования в template
  • сопоставление через parserServices

Это позволяет реализовывать правила, которые невозможны в чистом JavaScript-анализе.


Области видимости и связывание данных

Vue вводит собственную модель реактивности и связывания данных. В отличие от классического JavaScript, переменные могут использоваться в template без явного импорта в этом контексте.

vue-eslint-parser формирует специальную систему scope tracking:

  • глобальный scope
  • script scope
  • template scope
  • компонентный scope

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


Обработка директив Vue

Vue директивы, такие как:

  • v-if
  • v-for
  • v-bind
  • v-model

интерпретируются как специальные атрибуты AST-узлов.

Каждая директива преобразуется в структурированное представление:

  • name директивы
  • argument (например, :value)
  • ex * pression (JavaScript выражение)

Это позволяет ESLint анализировать корректность использования директив и их выражений.


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

При использовании TypeScript в Vue проектах часто применяется связка:

  • vue-eslint-parser
  • @typescript-eslint/parser

В этом случае происходит каскадный парсинг:

  1. Vue parser обрабатывает SFC
  2. Script блок передаётся TypeScript парсеру
  3. Возвращается TypeScript AST
  4. Vue parser интегрирует результат в общий AST

Такой подход обеспечивает проверку типов и синтаксический анализ одновременно.


Проблемы совместимости и ограничения

Несмотря на гибкость, архитектура имеет ряд ограничений:

  • различие между template AST и JS AST усложняет правила
  • не все ESLint правила корректно работают с Vue AST
  • необходимость использования parserServices для сложных проверок
  • повышенная сложность дебага AST

Также некоторые инструменты анализа кода, ориентированные на чистый ESTree, не поддерживают Vue-структуру без адаптации.


Механизм трансформации координат

Одной из сложных задач является сопоставление позиций кода:

  • template имеет собственные координаты
  • script имеет стандартные JS координаты
  • итоговый Vue AST должен объединять их

Для этого используется mapping слой, который преобразует:

  • line/column template → source file
  • expression → оригинальный JS код

Это критически важно для корректного отображения ошибок ESLint.


Влияние на разработку ESLint правил

При разработке правил для Vue необходимо учитывать:

  • наличие двух языковых контекстов
  • необходимость работы через parserServices
  • различие между runtime и template scope
  • особенности reactive bindings

Правила могут быть:

  • script-only (работают как обычный ESLint)
  • template-aware (работают с AST шаблона)
  • hybrid (используют оба контекста)

Hybrid-правила наиболее сложны, но позволяют реализовывать глубокий анализ компонентов.


Обработка JSX в Vue контексте

При использовании JSX внутри Vue (например, через Babel):

  • template может отсутствовать
  • script блок содержит JSX
  • parserOptions должен поддерживать JSX-парсер

В этом случае vue-eslint-parser фактически работает как контейнер, передавая весь JS в Babel-парсер, но сохраняя структуру Vue файла для возможного расширенного анализа.


Роль в современной архитектуре Vue инструментов

vue-eslint-parser выступает базовым компонентом для:

  • статического анализа Vue проектов
  • интеграции с ESLint правилами сообщества Vue
  • поддержки больших монорепозиториев Vue приложений
  • обеспечения качества кода на уровне SFC

Он является связующим звеном между декларативной природой Vue и императивной моделью JavaScript анализа, используемой ESLint.