Parcel использует Babel как один из ключевых трансформеров JavaScript-кода. Его задача — преобразование современного ECMAScript в код, совместимый с целевыми окружениями, а также поддержка JSX, TypeScript-синтаксиса (в связке с TypeScript-трансформером), экспериментальных предложений языка и пользовательских плагинов.
Внутри пайплайна Parcel трансформация JavaScript проходит через несколько этапов: анализ модуля, применение нужного трансформера и генерация оптимизированного бандла. Babel подключается автоматически, если в проекте обнаруживаются соответствующие конфигурационные файлы или синтаксические конструкции, требующие трансляции.
Babel поддерживает несколько форматов конфигурации:
babel.config.js — глобальная конфигурация уровня
проекта или монорепозитория.babelrc — локальная конфигурация, привязанная к
директорииpackage.json → babel —
inline-конфигурацияParcel учитывает все три варианта, но приоритет и область действия зависят от структуры проекта и режима сборки.
babel.config.js является наиболее универсальным
вариантом, так как применяется ко всему графу зависимостей, включая
внешние пакеты, если это не ограничено явно.
Parcel не требует ручного подключения Babel-конфигурации. Достаточно
наличия файла babel.config.js в корне проекта.
Типовой сценарий:
project/
src/
index.js
babel.config.js
package.json
После обнаружения файла Parcel автоматически подключает Babel и использует его как трансформер для всех модулей, которые проходят через JS pipeline.
Важная особенность заключается в том, что Parcel не «импортирует»
конфигурацию вручную, а считывает её через стандартный Babel API
(@babel/core). Это означает, что любые изменения в
конфигурации влияют на поведение трансформации без дополнительных шагов
интеграции.
При старте сборки Parcel выполняет следующие действия:
Обходит дерево зависимостей проекта
Определяет тип каждого модуля
Для JavaScript-файлов проверяет наличие Babel-конфигурации
Если babel.config.js найден:
Кэширует результат трансформации для ускорения повторных сборок
Важно, что babel.config.js имеет глобальный характер.
Это означает, что он может влиять не только на код проекта, но и на
зависимости в node_modules, если Parcel не исключает их
явно через резолвер или настройки транспиляции.
Базовая конфигурация для современного проекта:
module.exports = function (api) {
api.cache(true);
return {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['last 2 versions', '> 1%']
},
modules: false
}
],
'@babel/preset-react'
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-syntax-dynamic-import'
]
};
};
Ключевая особенность — использование функции вместо объекта. Это
позволяет включать кэширование через api.cache, что
критично для Parcel, так как он активно использует файловый кэш между
сборками.
Parcel не накладывает ограничений на состав Babel-конфигурации. Поддерживаются все стандартные пресеты и плагины.
Наиболее распространённые сценарии:
@babel/preset-env для управления совместимостью@babel/preset-react для JSX@babel/preset-typescript при работе с TS без отдельного
компилятора@babel/plugin-transform-runtime для уменьшения
дублирования вспомогательных функцийПример расширенной конфигурации:
module.exports = function (api) {
api.cache(true);
return {
presets: [
'@babel/preset-react',
[
'@babel/preset-env',
{
targets: {
node: '16',
browsers: ['defaults']
},
bugfixes: true
}
]
],
plugins: [
'@babel/plugin-transform-runtime',
'@babel/plugin-proposal-object-rest-spread',
process.env.NODE_ENV === 'production' && 'babel-plugin-transform-remove-console'
].filter(Boolean)
};
};
Parcel корректно обрабатывает условные плагины, если итоговый массив возвращается в валидной форме.
Разница между двумя форматами становится критичной в крупных проектах.
.babelrc:
node_modulesbabel.config.js:
Parcel приоритетно использует babel.config.js, если он
присутствует, так как он уменьшает количество неоднозначностей при
построении dependency graph.
В монорепозиториях babel.config.js становится
центральной точкой управления трансформацией всех пакетов.
Структура:
repo/
babel.config.js
packages/
app/
ui/
shared/
Parcel при сборке каждого пакета поднимается вверх по дереву каталогов и обнаруживает корневую Babel-конфигурацию.
Типичный сценарий — использование overrides:
module.exports = function (api) {
api.cache(true);
return {
presets: ['@babel/preset-env'],
overrides: [
{
test: './packages/app',
presets: ['@babel/preset-react']
},
{
test: './packages/ui',
presets: ['@babel/preset-typescript']
}
]
};
};
Такой подход позволяет централизованно управлять разными сборочными требованиями внутри одного Parcel-проекта.
Parcel активно кэширует результаты Babel-трансформации. Изменение
babel.config.js приводит к инвалидированию кэша, но только
при корректном отслеживании зависимостей.
Особенности поведения:
presets или plugins полностью
инвалидирует JS-кэшNODE_ENV могут требовать
перезапуска сборкиapi.cache(true) ускоряет повторные
сборкиПри нестабильном кэшировании часто наблюдаются ситуации, когда старые
трансформации продолжают применяться до очистки
.parcel-cache.
Одна из распространённых проблем — конфигурация Babel не применяется к части файлов. Причины обычно связаны с областью видимости конфигурации.
Основные сценарии:
.babelrc и babel.config.jsnode_modules из трансформации Parceltest или ignore правилаВторой частый случай — плагины не работают из-за неправильного порядка:
Также встречаются проблемы с динамическими импортами:
@babel/plugin-syntax-dynamic-import в старых
конфигурацияхpreset-env без корректных
targetsДиагностика обычно опирается на анализ итогового AST и логов Parcel в режиме verbose, где видно, какой трансформер применён к каждому модулю.