Заміна ESLint та Prettier на Biome: швидкість проти правила Hooks, яке вам все ще потрібне
Час виконання тестів у Biome порівняно з ESLint та Prettier, різниця між react-hooks та exhaustive-deps, а також коли під час подвійної роботи один плагін ESLint є найкращим варіантом міграції.
Маркетингові пости пропонують бінарний файл Rust, одну конфігурацію та приріст продуктивності від 20 до 50 разів. Після цього було проведено тестування з чотирма маршрутами, а потім підраховано кількість ситуацій, коли діагностика не функціонувала.
Один бінарний файл проти наборів плагінів – час виконання скоротився, але охоплення одного важливого правила – ні.
Перегляньте файл package.json.
Підрахуйте залежності, пов’язані з лінтингом. Проєкти, які все ще включають eslint, prettier, eslint-config-prettier, eslint-plugin-react-hooks та плагін-парсер, сплачують „тихий податок“ за кожен push. Biome просуває себе як єдиний виконуваний файл для форматування, лінтингу та сортування імпортів.
У тій лабораторії поруч із існуючою інструментальною сукупністю ESLint було додано Biome. Обидві пайплайни проходили таймінг. Потім ESLint було видалено. У діагностичному інструменті, який від нього залежав, не було аналога Biome, який вважався безпечним. Пайплайн пройшов успішно, а клас помилок, який раніше блокував роботу через цей діагностичний інструмент, знову з’явився у фіч-гілці.
Гілка знову підключала websocket при зміні теми — це класична проблема залежностей від ефектів. Biome залишалося мовчазним.
Речення, яке насправді публікує Biome
Офіційно Biome форматує код із приблизно 97% узгодженістю з Prettier та перевіряє його за допомогою великого набору правил, запозичених з ESLint та typescript-eslint. Налаштування знаходяться у файлі biome.json. Щоденне використання виглядає так: pnpm exec biome check --write.
У пишних постах не згадується те, що деякі менш відомі плагіни та внутрішні правила все ще можуть бути відсутніми. Треба або залишити ESLint для цих випадків, або перенести логіку.
Швидкість легко полюбити. Відсутність покриття — це оренда.
Фактично зафіксовані часи
У лабораторії були використані TypeScript, React та кілька серверних модулів — приблизно шістдесят файлів, що не належать до node_modules. Функція Instant Navigations не активувалась, тому вимірювався лише інструмент перевірки.
pnpm exec eslint . --max-warnings=0
pnpm exec prettier --check .
pnpm exec biome check .
По три пройдання кожен; медіани:
- Лише ESLint: 4,1 с
- Prettier
--check: 1,6 с - Спочатку ESLint, потім Prettier: 5,7 с
- Biome
check: 0,22 с
Це далеко не 50 разів. Порівняно з послідовною парою інструментів це приблизно 26 разів для невеликого проекту. У блогах часто згадують близько 10 тисяч файлів. У цих вимірюваннях використовувалося застосунок, який фактично розгортається. Тренд підтверджується; але завищений коефіцієнт — ні.
Під час оновлення коду Prettier та інші інструменти не погодилися щодо двох файлів — довгого обгортання JSX-пропу всередині InvoiceRow. Обгортання від Biome залишилося. Цифра 97% є точною; решта 3% стає проблемою лише тоді, коли команда обговорює кожен файл окремо.
Як перевірити це на своєму комп’ютері
pnpm add -D --save-exact @biomejs/biome
pnpm exec biome init
З’явиться файл biome.json. Запустіть Biome один раз, поки ще існує ESLint. Нічого не видаляйте, поки не буде письмовий список помилок ESLint, які Biome ніколи не фіксує.
pnpm exec eslint . -f unix > /tmp/eslint.txt
pnpm exec biome check --reporter=json > /tmp/biome.json
Порівняння показало, що більша частина елементів типу recommended збігається. Проблемна прогалина:
react-hooks/exhaustive-deps
Biome включає перевірки, пов’язані з хуками. Вони не збігалися з точними попередженнями, які раніше стосувалися ефекту socket. Після того, як CI видалив це правило, проблема з перепідключенням теми залишилася.
ESLint повернув помилку лише для одного плагіна:
{
"scripts": {
"lint": "biome check . && eslint app --plugin react-hooks --rule 'react-hooks/exhaustive-deps:error'"
}
}
Незграбно. Прозоро. Використання двох інструментів — це розумний сучасний компроміс, коли відсутнє правило має назву. Зберігання повного дерева ESLint «на випадок» зазвичай є марною тратою часу.
Перевіряйте ситуацію з редактором того ж вечора. Мовний сервер Biome замінив пару розширень; раптово попередження про гаки з’являлися лише в середовищі CI — ще гірше локально, якщо розширення ESLint не залишатиметься для цього конкретного правила. Краще бачити його у розділі /settings, ніж виявляти під час збірки вранці.
Що насправді швидше
Biome обробляє дерево як один нативний процес. ESLint — це Node разом із плагінами, часто доповнений Prettier. При шістдесяти файлах завантаження плагінів займає значну частину 4,1 секунди. При тисячах файлів обробка дерева стає домінуючою, і з’являються показники у масштабах великих проектів.
Biome 2 пропонує певну перевірку коду з урахуванням типів, але це не повний функціонал typescript-eslint. Якщо безперервна інтеграція все ще дозволяє використовувати parserOptions.project, оцінюйте роботу окремо — це саме той дорогий режим ESLint. Очікуйте недоліків порівняно зі старими налаштуваннями no-unsafe-*.
Вимкнення парсингу з урахуванням проекту призводить до скорочення часу виконання CI з приблизно 90 секунд до 8 секунд, але звинувачувати в цьому Biome є оманливим, адже просто була видалена функція перевірки типів. Скажіть це вголос, коли це трапиться.
Розрахунок витрат
Час обробки потоку даних: з 5,7 секунд до 0,22 секунди. Monorepos найбільше відчувають цю позитивну зміну. У малих додатках переважно покращується швидкість роботи на ноутбуці.
Правила: зникла одна перевірка залежностей; ESLint залишився для цього шляху.
Суперечки щодо форматування: два обгортки JSX; це можна виправити.
Редактор: два розширення об’єдналися в одне, а потім знову розділилися — приблизно рівність, зі швидшою перевіркою через CLI.
Увага: запуск у режимі Biome зеленого кольору — це не дерево зелених гачків. У запитах на внесення змін слід зазначати, хто саме позначив файл.
Залиште все як є або припиніть нічну зміну
Репозиторії типу Greenfield можуть почати використовувати Biome сьогодні ввечері для форматування та базової перевірки коду, повністю пропустивши Prettier.
Дерева типу Legacy слід запускати паралельно протягом приблизно тижня. Залиште ESLint лише для плагінів із назвами. Видаляйте невикористані конфігурації, а не лише кроки CI.
Залишайтеся з ESLint, коли саме користувацькі правила є основою продукту — та запишіть ці правила. Фраза „Можливо, нам знадобляться плагіни“ не є інвентаризацією.
Ніколи не відмовляйтеся від exhaustive-deps лише через те, що Biome працює швидко. Зміна теми доведе, навіщо це правило існує.
Важливі застереження, які варто чітко сформулювати
0,22 секунди проти 5,7 секунд — це результат обробки шістдесяти файлів на одному ноутбуці, а не корпусу з 10 тисяч файлів чи твердження про 56-кратну швидкість.
Розмір проміжку між гачками залежить від налаштувань та конфігурації біому в ту ніч. Перезапустіть biome rage та перевірте поточну діагностику гачків, перш ніж вважати цю діру постійною; ідентифікатори змінюються між версіями.
Інвентарі плагінів відрізняються. Якщо порядок імпорту через eslint-plugin-import є єдиним проблемним елементом, спробуйте використовувати функцію organize-imports від Biome протягом тижня.
Запустіть обидві програми. Перелічте проблеми ESLint, які залишилися після очищення даних за допомогою Biome.
Саме цей перелік є частиною роботи з міграції. Ті, хто залишився, використовують скрипт подвійної перевірки з чітким розподілом обов’язків.
Коли CI став зеленим та відбулося повторне підключення
ESLint разом із Prettier поступилися місцем Biome. Час перевірки шістдесяти файлів: 0,22 секунди проти 5,7 секунд. Бранч було об’єднано. Зміна теми знову підключила websocket. Раніше react-hooks/exhaustive-deps блокував таку модель; Biome не генерував відповідних сигналів.
Погана відповідь. Зупиніть роботу сокета доки “міграція не завершиться”. Клієнти втрачають можливість бачити актуальні дані.
Краща відповідь. Biome керує форматом та базовими правилами. ESLint залишається лише для одного плагіну в app.
{
"scripts": {
"lint": "biome check . && eslint app --plugin react-hooks --rule 'react-hooks/exhaustive-deps:error'"
}
}
Два підходи є ефективними, якщо названо відсутнє правило. Два підходи є марними, якщо залишається вся конфігурація ESLint. Різниці у форматуванні: два обгортки JSX; зберігається версія Biome.
Вимірюйте на власному проекті. Складіть список правил лише ESLint після того, як Biome буде очищений. Спочатку список; потім таймер.
Команди та результати лабораторної сесії
Версії до початку роботи: Node 24, TypeScript 7, Next 16.3. Зберігайте їх у записку лабораторії, щоб наступна сесія не була спробою вгадування.
node -v
pnpm exec tsc -v
pnpm exec next --version
Розмістіть ці три рядки на початку записки. Якщо щось суттєво не відповідає дотримуваній інструкції, зупиніться — подальші команди можуть тихо ввести в оману.
Наступний крок прогулянки по маршруту:
pnpm exec next dev
Натисніть /, /invoices, /invoices/1, /settings, а потім знову /invoices. Залиште у DevTools опцію preserve-log увімкненою. Зробіть скріншот інтерфейсу фільтра та URL-адреси; ця пара буде корисною під час подібних експериментів.
Перевірка типів:
pnpm exec tsc --noEmit --pretty false
echo $?
Код вихіду 0 не є готовим продуктом. Він лише відкриває шлях до перевірок під час виконання.
Після цього знову запустіть команди виявлення з розділу „Як побачити це на вашому пристрої“. Не пропускайте їх через те, що вище вказані числа. Інший пристрій, температура навколишнього середовища чи активні вкладки Chrome можуть більше вплинути на обсяг пам’яті, тривалість перевірки та результати вимірювань часу, ніж оновлення фреймворку.
Зберігайте однорядковий запис про невдалий спробу виправлення: „Спробував X, все одно бачу Y“. Версія, команда, результат та це речення створюють корисний матеріал для подальших досліджень. Скріншоти з маркетингових матеріалів — ні.
Щоденник невдач
Видалення ESLint у той самий день, коли з’явився Biome, знову спричинило проблему з сокетом. Відновлення одного плагіна повернуло можливість аналізу коду.
Спроба відтворити поведінку типсцріпт-еслінт, яка враховує особливості проекту, у Biome 2 призвела до часткового збігу. Старий набір правил no-unsafe-* не збігався. Якщо прикидатися інакше, проблема зникала.
Довгий конфлікт щодо форматування властивостей JSX закінчився прийняттям Biome.
У редакторі інструменти LSP від Biome витіснили розширення Prettier та ESLint. Попередження щодо хуків потім з’являлися лише у середовищі CI, тому розширення ESLint залишилося для цього правила. Два розширення все одно кращі за п’ять.
Чек-лист перед видаленням ESLint
- [ ] Команда
biome checkзавершується без проблем - [ ] Правила, які стосуються лише ESLint, записані
- [ ] Іменовані плагіни або зберігаються, або свідомо відкидаються
- [ ] У інструменті
exhaustive-depsє надійний аналог, інакше ESLint залишається для цього
0,22 с проти 5,7 с — це шістдесят файлів. Перевиміряйте локально. Переперевірьте діагностику гачків у встановленому Biome, перш ніж вважати різницю постійною.
Примітка щодо виробництва з додатку для рахунків-фактур
CI зберігає секунди звичайного годинника. Під час демонстрації зміна теми призвела до повторного підключення через websocket, оскільки покриття гачків зникло. Секунди — це не кінцевий результат; важливий живий підсумок.
Краще обирати повільнішу перевірку, яка виявляє повторні підключення, ніж швидку перевірку, яка їх пропускає. Поєднання Biome зі швидкістю 0,22 с та одним плагіном ESLint також є хорошою пропозицією. Нові репозиторії можуть починатися лише з Biome та додавати ESLint, як тільки буде придумано правило. Старі репозиторії не отримають жодної користі від таких формальностей.
Команди
pnpm exec eslint . --max-warnings=0
pnpm exec prettier --check .
pnpm exec biome check .
Запустіть тричі; візьміть медіани. Запишіть результати ESLint, Prettier та Biome. Виведіть вихід ESLint у форматі Unix та складіть таблицю з результатами, які Biome не виявив. Помістіть цю таблицю у pull request; розглядайте інформацію про час виконання як примітку.
Значущою є та правило, у якої немає аналогічної.
Вправа для читача з реальним проектом
Виберіть репозиторій, який використовується у реальних проектах, а не сандбокс. Запишіть час виконання команд eslint ., prettier --check . та biome check . — по три запуски кожної. Складіть таблицю з медіанами та кількістю файлів.
Вручну створіть таблицю з різницями у правилах; автоматизоване перейменування часто призводить до помилок. Випишіть усі проблеми ESLint, які залишилися після обробки Biome. Порожня список означає, що ESLint може залишитися. Якщо список містить react-hooks/exhaustive-deps або критичний для продукту користувацький плагін, залиште цю частину.
Створіть гілку з хуком, у якого відсутня залежність, про існування якої відомо. Подивіться, який інструмент видає попередження. Саме через цю гілку порівняння не є просто конкуренцією.
Збережіть таблицю та список правил. Уникайте запиту на об’єднання типу “switched to Biome”, який лише видаляє пакети. Видалення — це кінцевий крок, а не початкова дія.