← Назад к вопросам

Как совместить работу linter и Sonar?

2.0 Middle🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Совместная работа Linter и Sonar

Это вопрос про качество кода. Разберём как эти инструменты работают вместе.

Что такое Linter?

Linter проверяет код на ошибки и стиль ВО ВРЕМЯ разработки:

// ESLint конфиг (.eslintrc.json)
{
  "extends": ["eslint:recommended"],
  "rules": {
    "no-unused-vars": "error",
    "semi": ["error", "always"],
    "quotes": ["error", "single"],
    "indent": ["error", 2]
  }
}

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

  • Работает в реальном времени
  • Показывает ошибки в IDE
  • Проверяет синтаксис
  • Проверяет стиль
  • Работает локально
  • Быстро

Что такое SonarQube/SonarCloud?

Sonar анализирует код на глубокие проблемы ПОСЛЕ коммита:

# sonar-project.properties
sonar.projectKey=myapp
sonar.sources=src
sonar.exclusions=**/*.test.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.qualityGate=Sonar%20way

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

  • Работает в CI/CD pipeline
  • Проверяет качество кода
  • Анализирует код покрытие
  • Ищет уязвимости безопасности
  • Проверяет потенциальные баги
  • Дорого (требует сервер)

Разница между ними

КритерийLinterSonar
КогдаВо время разработкиПосле коммита (CI/CD)
СкоростьОчень быстроМедленнее
Типы проверокСинтаксис, стильСтиль, баги, безопасность
ПокрытиеФайл целикомЛогика, сложность
СтоимостьБесплатноПлатный сервис
ЛокальноДаНет (требует сервер)

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

# Установка
npm install --save-dev eslint
npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin

# Инициализация
npx eslint --init
// .eslintrc.js
module.exports = {
  parser: '@typescript-eslint/parser',
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended'
  ],
  rules: {
    // Синтаксис
    'no-console': 'warn',
    'no-debugger': 'error',
    'no-unused-vars': 'error',
    
    // Стиль
    'semi': ['error', 'always'],
    'quotes': ['error', 'single'],
    'indent': ['error', 2],
    
    // Лучшие практики
    'eqeqeq': 'error', // === вместо ==
    'curly': 'error', // обязательны скобки
    'no-var': 'error' // используй let/const
  }
};

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

# Установка Sonar Scanner
npm install --save-dev sonarqube-scanner

# Запуск анализа
npx sonarqube-scanner \
  -Dsonar.projectKey=myapp \
  -Dsonar.sources=src \
  -Dsonar.host.url=https://sonar.example.com \
  -Dsonar.login=TOKEN
# sonar-project.properties
sonar.projectKey=myapp
sonar.projectName=My App
sonar.projectVersion=1.0

# Исходный код
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/*.test.js,node_modules/**

# Покрытие кода
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.typescript.lcov.reportPaths=coverage/lcov.info

# Правила
sonar.qualityGate=Sonar%20way

Интеграция в CI/CD (GitHub Actions)

# .github/workflows/sonar.yml
name: SonarQube Analysis

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      # Запуск ESLint
      - name: Run ESLint
        run: npm run lint
      
      # Запуск тестов с покрытием
      - name: Run tests
        run: npm run test:coverage
      
      # Запуск SonarQube анализа
      - name: SonarQube Scan
        uses: sonarsource/sonarcloud-github-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

Pre-commit hook для ESLint

# Установка
npm install --save-dev husky lint-staged
npx husky install

# Создание hook
npx husky add .husky/pre-commit "npx lint-staged"
// package.json
{
  "lint-staged": {
    "src/**/*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

Процесс:

1. Разработчик изменил файлы
2. git commit файлы
3. Pre-commit hook запускается
4. lint-staged запускает ESLint
5. Если ошибки - fix их автоматически
6. Если критичные ошибки - блокирует коммит
7. Иначе коммит продолжается

Типичная рабочий процесс

┌─────────────────────────────────────┐
│ 1. РАЗРАБОТЧИК ПИШЕТ КОД            │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 2. ESLint проверяет в IDE           │
│    - Показывает ошибки red squiggly │
│    - Предлагает автофикс            │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 3. Разработчик фиксит ошибки        │
│    npm run lint --fix               │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 4. Разработчик коммитит             │
│    git commit -m "..."              │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 5. Pre-commit hook запускается      │
│    - Дополнительная проверка        │
│    - Блокирует плохой код           │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 6. Код pushится в репозиторий       │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 7. CI/CD pipeline запускается       │
│    - Запускаются тесты              │
│    - Проверяется покрытие           │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 8. SonarQube анализирует            │
│    - Глубокая проверка качества     │
│    - Отчёт на сервер                │
└─────────────────────────────────────┘
            ↓
┌─────────────────────────────────────┐
│ 9. Quality Gate проверка            │
│    - Если не прошла -> fail pipeline │
│    - Если прошла -> merge разрешена │
└─────────────────────────────────────┘

Совместная конфигурация

// .eslintrc.js
module.exports = {
  extends: ['eslint:recommended'],
  rules: {
    // Синхронизируй с Sonar правилами
    'no-console': 'warn', // Sonar также проверяет это
    'no-unused-vars': 'error',
    'no-duplicate-imports': 'error',
    'no-await-in-loop': 'warn', // Performance
    'complexity': ['warn', 10], // Цикломатическая сложность
  }
};

Практический пример

// Код с ошибками
function processData(data) {
  var result = []; // ESLint: используй const/let
  console.log('Processing'); // ESLint: warn, Sonar: code smell
  
  // Sonar: это слишком сложно (complexity > 10)
  for (const item of data) {
    if (item.valid) {
      if (item.active) {
        if (item.verified) {
          result.push(item.id); // N+1 сложность
        }
      }
    }
  }
  
  return result;
}

// Исправленный код
function processData(data) {
  const result = data
    .filter(item => item.valid && item.active && item.verified)
    .map(item => item.id);
  
  return result; // Complexity = 1, лучше читаемость
}

Рекомендации

ЛОКАЛЬНО:
✓ ESLint для быстрой обратной связи
✓ Prettier для форматирования
✓ Pre-commit hooks для блокировки плохого кода
✓ IDE подсказки

В CI/CD:
✓ Запускай ESLint
✓ Запускай тесты
✓ Собирай покрытие кода
✓ Запускай SonarQube анализ
✓ Проверяй quality gate
✓ Блокируй merge если не прошли

Мой подход

# package.json скрипты
{
  "scripts": {
    "lint": "eslint src --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
    "format": "prettier --write src/**/*.{js,jsx,ts,tsx}",
    "test": "jest --coverage",
    "sonar": "sonar-scanner",
    "quality": "npm run lint && npm run test && npm run sonar"
  }
}

Итого

Лinter и Sonar работают вместе:

  1. ESLint - первая линия защиты (разработчик)
  2. Pre-commit hooks - вторая линия защиты (локально)
  3. SonarQube - третья линия защиты (CI/CD)
  4. Quality Gate - финальная проверка (блокировка merge)

Такая многоуровневая защита обеспечивает высокое качество кода!

Как совместить работу linter и Sonar? | PrepBro