Качество кода
Проект использует комплексный набор инструментов для обеспечения качества и консистентности кода.
ESLint
Конфигурация: eslint.config.mjs (Flat Config v9+)
ESLint плагины
@angular-eslint
- Правила для Angular-специфичного кода
- Проверка директив, компонентов, инъекции
- Правило
prefer-inject: используйтеinject()вместо конструктора
sonarjs
- Обнаружение vulnerabilities
- Правила:
no-inverted-boolean-check,prefer-immediate-return
unicorn
- Best practices JavaScript/TypeScript
- Более 70 правил для качественного кода
- Правила:
throw-new-error,prefer-modern-dom-apisи др.
simple-import-sort
- Автоматическая сортировка импортов
- Группирует: external → internal → relative
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:stagedStylelint
Конфигурация: .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:stagedPrettier
Конфигурация: автоматическая (используется 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 --stagedTypeScript
Конфигурация: 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"
}
}
}Следующие шаги
- Workflow разработки — Git hooks и автоматизация
- Правила кода — стандарты написания
- Архитектура — структура проекта