Настройка lint-staged для проверки кода перед коммитом
lint-staged запускает команды только для файлов добавленных в git staging area. Разница принципиальная: ESLint на весь проект из 500 файлов занимает 20–30 секунд, ESLint только на 3 изменённых файла — меньше секунды. Это делает pre-commit проверку практически незаметной.
Установка
npm install --save-dev lint-staged
Обычно устанавливается вместе с Husky. .husky/pre-commit должен содержать:
npx lint-staged
Конфигурация
lint-staged.config.mjs:
export default {
// TypeScript и JavaScript
'**/*.{ts,tsx,js,jsx}': [
'eslint --fix --max-warnings 0',
'prettier --write',
],
// CSS и SCSS
'**/*.{css,scss}': [
'stylelint --fix',
'prettier --write',
],
// JSON, Markdown, YAML — только форматирование
'**/*.{json,md,yml,yaml}': [
'prettier --write',
],
};
Порядок команд важен: сначала линтер (может изменить код), потом форматтер (приводит к единому виду).
Конфигурация в package.json
Альтернативно можно объявить прямо в package.json:
{
"lint-staged": {
"**/*.{ts,tsx,js,jsx}": [
"eslint --fix",
"prettier --write"
],
"**/*.{css,scss}": [
"stylelint --fix",
"prettier --write"
]
}
}
TypeScript typecheck на staged файлах
Проблема: tsc --noEmit не принимает список файлов — он проверяет весь проект. Обойти это можно через скрипт-обёртку:
// scripts/typecheck-staged.mjs
import { execSync } from 'node:child_process';
try {
execSync('tsc --noEmit --incremental', { stdio: 'inherit' });
} catch {
process.exit(1);
}
// lint-staged.config.mjs
export default {
'**/*.{ts,tsx}': [
'eslint --fix',
'prettier --write',
() => 'node scripts/typecheck-staged.mjs', // функция — игнорирует список файлов
],
};
() => 'command' — когда команда возвращается функцией, lint-staged не передаёт ей список файлов как аргументы.
Параллельный запуск
По умолчанию lint-staged запускает команды для разных glob-паттернов параллельно. Если это вызывает проблемы (например, два процесса пишут в один файл):
export default {
concurrent: false, // последовательный запуск
'**/*.{ts,tsx,js,jsx}': ['eslint --fix'],
};
Дополнительные проверки
Проверка размера файлов (случайно не закоммитить большой бинарник):
npm install --save-dev bundlesize
export default {
'**/*.{js,css}': [
'bundlesize',
],
// Запрет на коммит файлов > 500KB
'**/*': (files) => {
const { statSync } = require('node:fs');
const large = files.filter(f => {
try { return statSync(f).size > 512 * 1024; }
catch { return false; }
});
if (large.length) {
console.error('Large files:', large);
process.exit(1);
}
},
};
Проверка на secrets через git-secrets или detect-secrets:
export default {
'**/*': 'detect-secrets scan',
'**/*.{ts,tsx,js,jsx}': ['eslint --fix', 'prettier --write'],
};
Отладка
# Посмотреть что будет запущено без реального запуска
npx lint-staged --debug --dry-run
Вывод показывает: какие файлы попали под какие паттерны, какие команды будут выполнены.
Сроки
Настройка lint-staged с ESLint и Prettier: 30–60 минут. Добавление typecheck и кастомных проверок: ещё 1–2 часа.







