Skip to content

Качество кода

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

ESLint

Конфигурация: eslint.config.mjs (Flat Config v9+)

ESLint плагины

  1. @angular-eslint

    • Правила для Angular-специфичного кода
    • Проверка директив, компонентов, инъекции
    • Правило prefer-inject: используйте inject() вместо конструктора
  2. sonarjs

    • Обнаружение vulnerabilities
    • Правила: no-inverted-boolean-check, prefer-immediate-return
  3. unicorn

    • Best practices JavaScript/TypeScript
    • Более 70 правил для качественного кода
    • Правила: throw-new-error, prefer-modern-dom-apis и др.
  4. simple-import-sort

    • Автоматическая сортировка импортов
    • Группирует: external → internal → relative
  5. unused-imports

    • Удаление неиспользуемых импортов
    • Проверка неиспользуемых переменных (кроме _ префикса)

Основные правила ESLint

Обязательные (Error)

typescript
// ✅ Правильно
const message = "Hello";
if (!value) return;
const sum = 2 + 3;
const equals = a === b;

// ❌ Неправильно
var message = "Hello"; // no-var
if (value) {
	return;
} // no-else-return
const sum = 2 + 3; // space-infix-ops
const equals = a == b; // eqeqeq

Стиль кода

typescript
// Обязательные скобки
if (condition) { /* ... */ }    // curly: error

// Правильный spacing
{ a: 1, b: 2 }                   // object-curly-spacing
function test(param) {}          // space-before-function-paren

// Правильные стрелки
const fn = () => console.log();  // arrow-parens

// Импорты отсортированы
import { Component } from "@angular/core";
import { OnInit } from "@angular/core";
import { Component } from "./component";

Angular специфичные

typescript
// ✅ Правильно
@Component({
  selector: "app-my-component",  // kebab-case
  standalone: true
})
export class MyComponent {}

@Directive({
  selector: "[appHighlight]"     // camelCase с app префиксом
})
export class HighlightDirective {}

constructor(private router = inject(Router)) {} // prefer-inject

// ❌ Неправильно
@Component({
  selector: "MyComponent"        // не kebab-case
})

[myHighlight]                    // неправильный префикс

Проверка ESLint

bash
# Проверить все файлы в src/
npm run lint:check

# Автоисправление
npm run lint:fix

# Проверка на staged файлы
npm run lint:staged

Stylelint

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

SCSS плагины

  • stylelint-scss — поддержка SCSS синтаксиса и правил

Основные правила SCSS

Переменные

scss
// ✅ Правильно
$margin-top: 10px;
$margin: $margin-top 0 20px;

// ❌ Неправильно
$marginTop: 10px; // kebab-case
margin: 0 0 20px 0; // должны быть переменные

At-правила

scss
// ✅ Правильно
@mixin button-reset {
	/* ... */
}

@mixin button-hover {
	/* ... */
}

// ❌ Неправильно
@mixin buttonReset {
	// kebab-case
}

Цвета

scss
// ✅ Правильно
$color: #ffffff; // long hex
$opacity: 50%; // percentage notation

// ❌ Неправильно
$color: #fff; // short hex
$opacity: 0.5; // numeric notation

Длины

scss
// ✅ Правильно
$margin: 0; // zero без unit
$padding: 10px;

// ❌ Неправильно
$margin: 0px; // zero с unit

Проверка Stylelint

bash
# Проверить все SCSS
npm run slint:check

# Автоисправление
npm run slint:fix

# Проверка на staged файлы
npm run slint:staged

Prettier

Конфигурация: автоматическая (используется ESLint правила)

Prettier автоматически форматирует код при:

  • Pre-commit hook (pretty-quick --staged)
  • Ручное выполнение (npm run format:write)

Форматирование

bash
# Проверить форматирование
npm run format:check

# Отформатировать все файлы
npm run format:write

# Форматирование на staged файлах (в pre-commit)
npx pretty-quick --staged

TypeScript

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

Strict Mode

Все файлы компилируются с strict: true:

typescript
// ✅ Типизировано
const user: IUser = {
	id: "uuid",
	email: "user@example.com"
};

// ❌ Не типизировано
const user: any = {
	/* ... */
};
const obj = {
	/* ... */
}; // type: unknown

Важные настройки

json
{
	"compilerOptions": {
		"strict": true,
		"strictNullChecks": true,
		"strictFunctionTypes": true,
		"strictBindCallApply": true,
		"strictPropertyInitialization": true,
		"noImplicitAny": true,
		"noImplicitThis": true,
		"alwaysStrict": true
	}
}

Проверка типов

bash
# Проверить типы без компиляции
npm run typecheck

# Это выполняется в pre-push hook

Комплексная проверка

Перед коммитом (автоматически)

bash
git commit -m "message"

# Выполняется:
# 1. removeComments:staged
# 2. removeReturnTypes:staged
# 3. pretty-quick --staged
# 4. lint-staged (ESLint + Stylelint)

Перед пушем (автоматически)

bash
git push

# Выполняется:
# 1. typecheck
# 2. lint:check
# 3. build --configuration=production

Ручная проверка

bash
# Все проверки перед пушем
npm run typecheck && npm run lint:check && npm run build:prod

# Или отдельно:
npm run typecheck          # TypeScript типы
npm run lint:check         # ESLint
npm run slint:check        # Stylelint
npm run format:check       # Prettier

Игнорирование правил

ESLint

typescript
// Отключить для строки
// eslint-disable-next-line rule-name
const suspicious = someFunction();

// Отключить для блока
/* eslint-disable rule-name */
const code = "something";
/* eslint-enable rule-name */

// Отключить для файла
/* eslint-disable */
// весь код в файле

Stylelint

scss
// Отключить для строки
// stylelint-disable-next-line
color: red;

// Отключить для блока
/* stylelint-disable */
.something {
	color: red;
}
/* stylelint-enable */

Best Practices

Делайте:

  • Регулярно запускайте npm run lint:fix во время разработки
  • Читайте сообщения об ошибках от linter
  • Используйте IDE extensions (ESLint, Stylelint)
  • Проверяйте типы перед пушем

Не делайте:

  • Не отключайте правила без причины
  • Не используйте any типы
  • Не коммитьте с ошибками линтера
  • Не игнорируйте ошибки TypeScript

IDE Extensions

VS Code

json
{
	"recommendations": [
		"dbaeumer.vscode-eslint",
		"stylelint.vscode-stylelint",
		"esbenp.prettier-vscode",
		"Angular.ng-template"
	]
}

Настройки .vscode/settings.json

json
{
	"editor.formatOnSave": true,
	"editor.defaultFormatter": "esbenp.prettier-vscode",
	"[typescript]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode",
		"editor.codeActionsOnSave": {
			"source.fixAll.eslint": "explicit"
		}
	},
	"[scss]": {
		"editor.codeActionsOnSave": {
			"source.fixAll.stylelint": "explicit"
		}
	}
}

Следующие шаги

SaaS Admin Documentation