Замена ESLint и Prettier на Biome: скорость против правила Hooks, которое вам всё ещё нужно
Время выполнения тестов в Biome по сравнению с ESLint и Prettier, разница между react-hooks и exhaustive-deps, а также когда при одновременном использовании нескольких плагинов ESLint честным решением является миграция на один из них.
В постах в социальных сетях рекламируется бинарный файл Rust, один конфигурационный файл и утверждается о 20–50-кратном увеличении производительности. После этого проводилось тестирование с четырьмя маршрутами, затем подсчитывалось количество ситуаций, когда диагностические функции Biome не справлялись со своей задачей.
Один бинарный файл против наборов плагинов — время выполнения сокращалось, однако охват обработки одного важного правила не улучшался.
Проверьте файл package.json.
Подсчитайте зависимости, связанные с инструментами проверки кода. Проекты, в которых по-прежнему используются eslint, prettier, eslint-config-prettier, eslint-plugin-react-hooks вместе с плагином-анализатором, платят «тихий налог» при каждой загрузке кода. Biome позиционирует себя как инструмент, объединяющий функции форматирования, проверки кода и сортировки импортов в один исполняемый файл.
В том лабораторном окружении рядом с существующей инструментальной платформой ESLint был добавлен Biome. Было измерено время работы обоих инструментов. Затем ESLint был удален. У одного из диагностических инструментов, от которого он зависел, не было аналога в Biome, который показался бы безопасным для использования. Инструментарий выдал положительный результат, а класс ошибок, который ранее мешал работе, исчез на фичной ветке.
При смене темы ветка снова подключала WebSocket — типичная проблема зависимости от эффектов. Biome оставался бездействующим.
Текст, который на самом деле выводит Biome
Официально Biome форматирует код с коэффициентом совпадения примерно 97% по стандартам Prettier и проверяет его с использованием большого набора правил, вдохновленных ESLint и typescript-eslint. Настройки хранятся в файле biome.json. Обычный способ вызова — pnpm exec biome check --write.
В публикациях, привлекающих внимание, не упоминается: могут отсутствовать менее известные плагины и внутренние правила. В таких случаях либо сохраняйте ESLint для обработки этих проблем, либо перенесите соответствующую логику в Biome.
Скорость легко полюбить. Отсутствие покрытия — это арендная плата.
Фактически зафиксированные времена
В лаборатории были использованы 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-*.
Отключение анализа с учётом проекта приводит к снижению времени обработки с примерно 90 секунд до 8 секунд, и приписывать этот результат Biome ошибочно, ведь просто убрали проверку с учётом типов. Говорите об этом вслух, когда это происходит.
Расчёт затрат
Время обработки в пайплайне: с 5,7 секунд до 0,22 секунды. Монорепозитории ощущают эти улучшения наиболее явно. У небольших приложений в основном ускоряется работа на ноутбуке.
Правила: исчезла одна проверка на зависимости; ESLint остался для этого пути.
Проблемы с форматированием: два обёртывания JSX; проблему можно решить.
Редактор: два расширения объединились в одно, затем одно из них снова исчезло — в целом ситуация примерно одинаковая, но проверка через CLI стала быстрее.
Внимание: запуск с использованием Biome в зеленом режиме не означает наличие дерева с зелеными хуками. В запросах на внесение изменений следует указать, кто именно отметил файл.
Оставьте всё как есть или прекратите ночную смену
Репозитории типа Greenfield могут начать использовать Biome сегодня вечером для форматирования и базовой проверки кода, полностью игнорируя инструмент Prettier.
У старых решений следует проводить двойные тесты в течение примерно недели. Сохраняйте ESLint только для специальных плагинов. Удаляйте ненужные настройки, а не просто шаги интеграционного тестирования.
Продолжайте использовать 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 в режиме сохранения логов. Запишите интерфейс фильтра и 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 или критически важными пользовательскими плагинами, сохраните эти элементы.
Откройте ветку с хуком, у которого отсутствующая зависимость действительно существует. Узнайте, какой инструмент выдает ошибку. Именно из-за этой ветки сравнение не является просто соревнованием.
Сохраните таблицу и список правил. Избегайте пул-реквестов типа «Переключить на Biome», которые удаляют только пакеты. Удаление — это заключительный шаг, а не первое действие.