Плагин @angular-eslint

Пакет @angular-eslint представляет собой набор инструментов и плагинов, обеспечивающих полноценную интеграцию ESLint в экосистему Angular. Он заменяет устаревший подход с TSLint и предоставляет единый механизм анализа TypeScript-кода, шаблонов Angular и конфигураций проектов.

Ключевая особенность архитектуры заключается в разделении ответственности между несколькими пакетами:

  • @angular-eslint/schematics — генерация и миграция конфигураций в Angular CLI-проектах
  • @angular-eslint/eslint-plugin — набор правил для TypeScript-кода Angular
  • @angular-eslint/eslint-plugin-template — правила для HTML-шаблонов Angular
  • @angular-eslint/template-parser — парсер Angular templates
  • @angular-eslint/builder — интеграция ESLint в Angular CLI build pipeline

Такое разделение позволяет независимо анализировать TypeScript и шаблоны, что критично для Angular, где логика распределена между .ts и .html.


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

Интеграция начинается с установки основных пакетов:

ng add @angular-eslint/schematics

Эта команда автоматически:

  • удаляет TSLint (если он присутствует)
  • устанавливает ESLint и плагины
  • создаёт конфигурационные файлы
  • обновляет angular.json

В случае ручной установки добавляются зависимости:

npm install --save-dev eslint @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/template-parser

Конфигурация ESLint в Angular-проекте

Основной файл конфигурации обычно представлен как .eslintrc.json:

{
  "root": true,
  "ignorePatterns": ["projects/**/*"],
  "overrides": [
    {
      "files": ["*.ts"],
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "project": ["tsconfig.json"],
        "createDefaultProgram": true
      },
      "plugins": ["@angular-eslint"],
      "extends": [
        "plugin:@angular-eslint/recommended",
        "plugin:@angular-eslint/template/process-inline-templates"
      ],
      "rules": {
        "@angular-eslint/directive-selector": [
          "error",
          {
            "type": "attribute",
            "prefix": "app",
            "style": "camelCase"
          }
        ],
        "@angular-eslint/component-selector": [
          "error",
          {
            "type": "element",
            "prefix": "app",
            "style": "kebab-case"
          }
        ]
      }
    },
    {
      "files": ["*.html"],
      "extends": ["plugin:@angular-eslint/template/recommended"],
      "rules": {}
    }
  ]
}

Основные категории правил @angular-eslint

Правила компонентов и директив

Эти правила обеспечивают единообразие структуры Angular-приложения.

  • @angular-eslint/component-class-suffix — проверяет суффикс классов компонентов
  • @angular-eslint/directive-class-suffix — проверяет директивы
  • @angular-eslint/no-input-rename — запрещает скрытое переименование входных свойств
  • @angular-eslint/no-output-rename — контролирует переименование событий

Особое внимание уделяется читаемости API компонентов, что критично для масштабируемых систем.


Правила селекторов

Селекторы являются ключевой частью архитектуры Angular.

"@angular-eslint/directive-selector": [
  "error",
  {
    "type": "attribute",
    "prefix": "app",
    "style": "camelCase"
  }
]

Контроль селекторов предотвращает:

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

Правила шаблонов Angular

Плагин @angular-eslint/eslint-plugin-template анализирует HTML-шаблоны:

  • @angular-eslint/template/no-negated-async — предотвращает сложные отрицания с async pipe
  • @angular-eslint/template/banana-in-box — проверяет корректность [(ngModel)]
  • @angular-eslint/template/no-call-expression — запрещает вызовы функций в шаблонах
  • @angular-eslint/template/accessibility-alt-text — проверяет наличие alt у изображений

Пример нарушения:

<div>{{ getUser().name }}</div>

Такой код приводит к частым перерендерингам и ухудшению производительности.


Парсер шаблонов Angular

Для анализа HTML используется специализированный парсер:

"parser": "@angular-eslint/template-parser"

Он позволяет ESLint понимать Angular-синтаксис:

  • структурные директивы *ngIf, *ngFor
  • биндинги [property]
  • события (click)
  • двухсторонние биндинги [(...)]

Без этого парсера стандартный ESLint не способен корректно интерпретировать Angular-шаблоны.


Интеграция с Angular CLI

@angular-eslint интегрируется в Angular CLI через builder:

"lint": {
  "builder": "@angular-eslint/builder:lint",
  "options": {
    "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
  }
}

Запуск анализа:

ng lint

Это позволяет:

  • использовать единый pipeline сборки
  • подключать ESLint к CI/CD
  • унифицировать проверку кода в командах

Миграция с TSLint

Исторически Angular использовал TSLint, но он был официально deprecated. @angular-eslint предоставляет инструменты миграции:

ng g @angular-eslint/schematics:convert-tslint-to-eslint

Миграция включает:

  • преобразование правил TSLint → ESLint
  • генерацию новой конфигурации
  • удаление устаревших зависимостей

Flat Config и современный ESLint (v9+)

Современные версии ESLint поддерживают flat config (eslint.config.js). @angular-eslint постепенно адаптируется к этой модели.

Пример:

import angular from '@angular-eslint/eslint-plugin';

export default [
  {
    files: ['**/*.ts'],
    languageOptions: {
      parser: require('@typescript-eslint/parser')
    },
    plugins: {
      '@angular-eslint': angular
    },
    rules: {
      '@angular-eslint/directive-selector': 'error'
    }
  }
];

Flat config упрощает:

  • объединение конфигураций
  • устранение cascading rules
  • повышение предсказуемости анализа

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

При больших Angular-приложениях ESLint может замедляться из-за анализа TypeScript project references. @angular-eslint учитывает это через:

  • createDefaultProgram: true (fallback режим)
  • разделение tsconfig по модулям
  • исключение node_modules и build artifacts
  • ленивый анализ шаблонов

Оптимизация особенно важна в монорепозиториях Nx.


Интеграция с Nx workspace

В экосистеме Nx @angular-eslint используется как стандартный линтер:

"lint": {
  "executor": "@nx/eslint:lint",
  "options": {
    "lintFilePatterns": ["apps/**/*.{ts,html}"]
  }
}

Nx добавляет:

  • кэширование результатов lint
  • параллельное выполнение
  • распределённый анализ в CI

Правила архитектурной чистоты

@angular-eslint позволяет реализовывать архитектурные ограничения:

  • запрет импорта между слоями
  • контроль зависимости feature modules
  • ограничение использования any
  • проверка баррель-экспортов

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

"rules": {
  "no-restricted-imports": [
    "error",
    {
      "patterns": ["../shared/*"]
    }
  ]
}

Кастомизация и расширение

Создание собственных правил выполняется через ESLint Rule API:

  • анализ AST TypeScript
  • анализ Angular template AST
  • использование context.report()

Пример концепции правила:

  • запрет прямого доступа к DOM через document
  • контроль использования Renderer2
  • проверка подписок без unsubscribe

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

Часто встречающиеся проблемы:

  • отсутствие template-parser → шаблоны не анализируются
  • неправильный parserOptions.project → ошибки типов
  • конфликт Angular ESLint и Prettier
  • избыточные правила, замедляющие CI
  • отсутствие разделения overrides для .ts и .html

Использование в крупных проектах

В масштабных Angular-приложениях @angular-eslint становится частью архитектурного слоя качества кода:

  • enforce code style на уровне CI
  • контроль API компонентов
  • защита от анти-паттернов в шаблонах
  • стандартизация структуры модулей
  • снижение технического долга через автоматическую проверку

Постепенное усложнение правил позволяет переходить от базовой проверки синтаксиса к полноценной статической архитектурной валидации проекта.