Вышел Babel 8. А нужен ли он?

• build

Введение

Неделю назад вышел Babel 8. С момента прошлого мажорного релиза прошло 8 лет. Что изменилось в одном из самых популярных фронтендерских инструментов? Давайте посмотрим.

А после вместе подумаем, нужен ли он в 2026м году.

Обновки

За время существования 7й версии много всего поменялось, и новая мажорная версия вместо новых фич предлагает в первую очередь новые дефолты и переход на новые стандарты.

1) Поддержка Node.js 22+. В первую очередь стоит начать с этого для обновления.

2) Теперь Babel поставляется в виде ESM-only пакета. Начинать новые проекты будет не очень сложно, а вот со старыми может всплыть много всего.

3) Babel теперь поставляется с типами. Тренд очевиден – всё меньше пакетов @types/* требуется устанавливать.

4) Смена дефолтных настроек. @babel/preset-env вместо перевода синтаксиса в ES5 теперь по дефолту берёт значение из browserslist (без явного указания это куда более новые браузеры). Конечно, ручные настройки никуда не делись и позволяют указать старые браузеры. Реакт теперь собирается в режиме automatic вместо classic и так далее.

5) Смена подхода в настройках. Вместо loose и spec мы получили assumptions, которые позволяют более точно настраивать ожидания (пардон за тавталогию).

6) Переименование и перераспределение пакетов. Полифилы для кода из core-js, доступные ранее через @babel/preset-env, переехали в отдельный пакет babel-plugin-polyfill-corejs3. Пачка пакетов переименовалась.

7) Много другого, про всё можно подробнее прочитать в гайде по миграции.

Нужен ли Babel?

Авторы в блоге задаются тем же вопросом, однако график установок на npm растёт год от года. Получается, Babel нужен, а все новомодные инструменты лишь громко забивают эфир?

Я думаю, всё же не совсем так:

  • Babel действительно один из старых и укоренившихся инструментов, проверенных временем. Работает, и работает надёжно, так зачем менять?
  • Babel ориентировался на плагины. Если вы написали плагины к нему, вряд ли вы побежите их переписывать под другой инструмент
  • Babel стал “инструментом для инструментов”, тем самым количество установок растёт рекурсивно

Пока все фичи из Babel не реализуют в других инструментах, он продолжит расти. А плато по установкам вообще вряд ли возможно в ближайшем будущем. Например, у jQuery за прошедший год тоже выросло число загрузок! Однако вряд ли кто скажет, что jQuery всё ещё супер-актуален и что его популярность растёт.

Давайте посмотрим на типовые задачи, которые выполняет Babel, а также на то, какие у нас есть альтернативы в других инструментах.

Готовые трансформации кода

Думаю, одно из самых популярных направлений – трансформация реакт-кода (jsx). Esbuild/SWC/oxc/rolldown имеют встроенную поддержку трансформации jsx, и делают это без Babel.

Если мы говорим о других популярных трансформациях, то это будут:

  • Выпиливание типов. Предоставляется широким набором инструментов из коробки либо готовым плагином
  • istanbul. Разметка кода для расчёта тестового покрытия. Скорее всего, приезжает в составе других инструментов (например, в Jest). Вряд ли вы импортируете его вручную
  • regenerator. При разработке для современных браузеров это как будто уже давно не нужно. При этом у плагина примерно четверть загрузок от @babel/core. Я бы понял какую-то долю для сборки кода под телевизоры или другие экзотические окружения, но четверть звучит так, как будто людям этот плагин приезжает зря.

Про сборку кода под старые окружения мы поговорим в следующем разделе

Трансформация кода под старый синтаксис

Или, как это модно сейчас называется, Syntax lowering. По сути, второй краеугольный камень, на котором стоит популярность Babel – @babel/preset-env.

Esbuild поддерживает ограниченный список таргетов, для которых он умеет подгонять выходной синтаксис, примерно Chrome 50+. Это позволяет трансформировать async-await в генераторы и ряд других вещей, но не дальше в прошлое.

SWC поддерживает цели вплоть до ES3. В этом плане как будто паритет с Babel.

Rolldown/oxc поддерживают в качестве цели ES2015. На первый взгляд, поддержка похожа на Esbuild.

В Rollup нет встроенного аналогичного механизма, в наличии есть плагины (тот же Babel).

TypeScript, несмотря на отказ от преобразования в ES5, успешно конвертит синтаксис в ES2015 и выше.

Полифилизация

Одна из знаковых фич @babel/preset-env – автоматическая вставка необходимых полифилов. Используете вы какой-нибудь Map.prototype.getOrInsert, и полифил соответствующего метода автоматически добавляется. А что по другим инструментам?

Esbuild/Rolldown/oxc/Rollup/TypeScript не умеют автоматически вставлять полифилы (из коробки).

SWC умеет в автоматическую вставку полифилов, и делает это в похожей на Babel манере. Правда, в доках говорится, что вариант “по использованию” может не находить использование методов в редких случаях (JS – динамический язык, ну вы поняли).

Для Vite есть официальный плагин @vitejs/plugin-legacy, который умеет собирать полифилы для старых браузеров. Но делает он это через… @babel/preset-env.

Кастомные трансформации

Теперь посмотрим в сторону кастомных трансформаций. Например, если нужно выпилить какой-то код, что-то заменить и так далее – Babel в своё время прекрасно для этого подходил. Хорошее апи, понятные примеры, а какие альтернативы?

Esbuild не позволяет как-либо взаимодействовать с AST. Есть вариант работать только со строкой с кодом, так что этот вариант не подходит.

SWC в первую очередь позволяет писать плагины на Rust. У меня нет такого опыта, поэтому не могу прокомментировать, насколько он хорош на практике. Однако я уверен, что далеко не все разработчики, которые готовы писать плагины к Babel, будут писать аналогичные плагины на Rust.

Есть и второй путь в SWC – можно использовать свойство plugin, которое принимает AST и позволяет его модифицировать с помощью JS. Насколько я понимаю, AST конвертится из нативного кода, а затем конвертируется обратно. Способ, в теории, рабочий (хоть и есть вопросы по совместимости формата AST с другими парсерами), однако отсутствие документации чётко намекают, что это скорее на свой страх и риск, чем для продакшенового кода.

Oxc предоставляет полноценное апи для Rust. а для JS только методы для парсинга. К тому же, будет очень сильно теряться скорость от конвертации данных из нативного кода в JS. Итого, возможно, это решение на JS и будет работать, но как будто не сильно отличается от варианта с ручным парсингом строки и генерацией обратно по AST. Ну или идти писать плагин для трансформации на Rust.

Табличка поддержки из коробки

Пара комментариев:

  • Речь именно про встроенные возможности. Плагинами можно и Babel в Rollup добавить, и всё будет
  • rspack имеет встроенный SWC, поэтому строчку про SWC в каком-то смысле можно распространять и на rspack
Syntax loweringTSJSXПолифилы
Babel
SWC
esbuild
Rolldown/oxc
TypeScript
Rollup

Итого

Я бы сказал, что часто задачи Babel сейчас могут решаться сторонними инструментами, а сам Babel уже не супер-инструмент, без которого не обойтись.

Трансформация кода под старый синтаксис – пожалуйста, куча разных инструментов. Аналогично и TS/JSX.

Автоматическая вставка полифилов – уже сложнее. Такое по итогу умеет только сам Babel и SWC. Но и необходимость этого реже, чем можно подумать (правда, проекты спокойно могут обойтись без этого). Также можно пойти и с другой стороны и ограничить используемые методы линтером.

В случае с кастомными преобразованиями кода всё сложнее. Если у вас есть такая задача, то у вас три пути:

  • Babel
  • Ручной парсинг/генерация другим инструментом на JS
  • Написание плагина на Rust для SWC/oxc

Стоит ли изучать Rust – вероятно, зависит от задачи.

А что вы думаете про использование Babel? Возможно, где-то я допустил ошибку или неточность? Всё возможно, так как далеко не все из этих инструментов использую. Пишите в комментариях.

Обсудить в Telegram

Почитать ещё посты

  • Вышел Rolldown 1.0
  • Автоматические размеры полей с field-sizing
  • text-fit: свойство, которое дождались
  • Декораторы отступов, или свойства, которые у нас уже давно были
  • Ищем баланс с помощью flex-wrap: balance