Babel -- транспиляция
Babel — JavaScript-компилятор, превращающий современный код (ES2020+, JSX, TypeScript) в более старый синтаксис, понятный целевым браузерам.
Зачем нужно
Браузеры и Node.js поддерживают разные версии JavaScript. Babel позволяет писать на новейшем синтаксисе (optional chaining, nullish coalescing, async/await, декораторы), не думая о совместимости: он автоматически преобразует код под нужные targets. Без Babel большинство современных фреймворков (React, Vue, Angular) не работали бы в старых браузерах.
Где используется
- React-проекты: транспиляция JSX →
React.createElement - Webpack/Vite/Rollup: как loader/plugin в цепочке сборки
- Jest: трансформация тестового кода перед выполнением
- Библиотеки: публикация в npm с поддержкой CJS и ESM одновременно
- TypeScript-проекты (как альтернатива tsc для транспиляции без проверки типов)
Основной контент
Принцип работы
Исходный код → [Parser] → AST → [Transform Plugins] → AST → [Generator] → Выходной код
Три стадии: parse (код в AST), transform (плагины меняют AST), generate (AST обратно в код).
Установка
npm install --save-dev @babel/core @babel/cli @babel/preset-env
Конфигурация (babel.config.json)
{
"presets": [
[
"@babel/preset-env",
{
"targets": "> 0.25%, not dead",
"useBuiltIns": "usage",
"corejs": 3
}
]
],
"plugins":
}
Что делает @babel/preset-env
// Исходный код (ES2020)
const result = user?.profile?.name ?? 'Anonymous';
const doubled = [1, 2, 3].map(x => x * 2);
// После транспиляции (ES5-совместимый)
var _user, _user$profile;
var result = (_user = user) === null || _user === void 0
? void 0
: (_user$profile = _user.profile) === null || _user$profile === void 0
? void 0
: _user$profile.name;
result = result !== null && result !== void 0 ? result : 'Anonymous';
var doubled = [1, 2, 3].map(function(x) { return x * 2; });
Preset для React (JSX)
npm install --save-dev @babel/preset-react
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
// JSX → JS
const el = <div className="box">Hello</div>;
// ↓
const el = React.createElement("div", { className: "box" }, "Hello");
Интеграция с Webpack
npm install --save-dev babel-loader
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: { loader: 'babel-loader' }
}
]
}
};
Частые ошибки
- Нет
@babel/runtimeсuseBuiltIns: "usage"— polyfill-код дублируется в каждом файле; нужен@babel/plugin-transform-runtime - Транспилируется
node_modules— медленная сборка; всегда добавляйexclude: /node_modules/ - Конфликт Babel и TypeScript — Babel стриппит типы, но не проверяет их; для проверки типов нужен отдельный
tsc --noEmit - Устаревший
.babelrc+babel.config.json— два файла конфигурации одновременно могут конфликтовать; используй один
Связанные темы
Ресурсы
- https://babeljs.io/docs/
- https://babeljs.io/repl — онлайн-playground для экспериментов
- https://github.com/nicolo-ribaudo/tc39-proposal-babel-integration