Плагин @rollup/plugin-babel обеспечивает интеграцию Rollup и Babel, позволяя выполнять транспиляцию JavaScript-кода во время сборки. Он используется для преобразования современного синтаксиса ECMAScript, JSX, TypeScript и других расширений языка в код, совместимый с требуемыми версиями браузеров или сред выполнения.
Без использования Babel Rollup занимается преимущественно анализом модулей, объединением зависимостей и оптимизацией итогового бандла. Поддержка старых браузеров и преобразование нестандартного синтаксиса являются задачей Babel.
Основные возможности плагина:
Установка выполняется через npm:
npm install --save-dev @rollup/plugin-babel @babel/core
Минимальный набор всегда включает:
npm install --save-dev \
@rollup/plugin-babel \
@babel/core
Для поддержки современных возможностей обычно дополнительно устанавливаются пресеты:
npm install --save-dev \
@babel/preset-env
Для React:
npm install --save-dev \
@babel/preset-react
Для TypeScript:
npm install --save-dev \
@babel/preset-typescript
Простейшая конфигурация Rollup:
import babel from '@rollup/plugin-babel';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
},
plugins: [
babel({
babelHelpers: 'bundled'
})
]
};
Ключевым параметром является:
babelHelpers
Без него плагин работать не будет.
Babel может добавлять в код различные вспомогательные функции.
Например:
class User {}
может превратиться в:
function _classCallCheck(instance, Constructor) {
// ...
}
Способ подключения таких функций определяется параметром
babelHelpers.
Поддерживаются несколько режимов.
Наиболее распространённый вариант.
babel({
babelHelpers: 'bundled'
})
Все helper-функции включаются внутрь итогового бандла.
Преимущества:
Недостаток:
Использует пакет Babel Runtime.
Установка:
npm install --save @babel/runtime
Конфигурация:
babel({
babelHelpers: 'runtime'
})
Пример настройки Babel:
{
"plugins": [
"@babel/plugin-transform-runtime"
]
}
Преимущества:
Недостаток:
Все helper-функции внедряются непосредственно в место использования.
babel({
babelHelpers: 'inline'
})
Используется редко.
Недостаток:
Предполагает подключение helper-функций извне.
babel({
babelHelpers: 'external'
})
Используется главным образом при разработке библиотек и специальных сценариях сборки.
Самый популярный пресет Babel — @babel/preset-env.
Создание файла:
{
"presets": [
"@babel/preset-env"
]
}
Либо:
babel({
babelHelpers: 'bundled',
presets: ['@babel/preset-env']
})
Пример исходного кода:
const sum = (a, b) => a + b;
После транспиляции:
var sum = function (a, b) {
return a + b;
};
Babel позволяет определять список поддерживаемых платформ.
Файл .browserslistrc:
> 0.5%
last 2 versions
not dead
Либо:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "90",
"firefox": "88"
}
}
]
]
}
В этом случае Babel будет выполнять только необходимые преобразования.
Плагин поддерживает фильтрацию файлов через include и
exclude.
babel({
babelHelpers: 'bundled',
include: ['src/**/*.js']
})
Будут обработаны только файлы из каталога src.
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**'
})
Наиболее распространённая настройка.
babel({
babelHelpers: 'bundled',
include: [
'src/**/*.js'
],
exclude: [
'src/vendor/**'
]
})
Для React необходим пресет:
npm install --save-dev @babel/preset-react
Конфигурация:
babel({
babelHelpers: 'bundled',
presets: ['@babel/preset-react']
})
Файл:
function App() {
return <h1>Hello</h1>;
}
После обработки JSX преобразуется в вызовы React API.
Современный React использует автоматический runtime.
Настройка:
{
"presets": [
[
"@babel/preset-react",
{
"runtime": "automatic"
}
]
]
}
Пример:
export default function App() {
return <div>Application</div>;
}
Импорт React вручную больше не требуется.
Babel способен обрабатывать TypeScript без использования компилятора TypeScript для генерации JavaScript.
Установка:
npm install --save-dev \
@babel/preset-typescript
Конфигурация:
babel({
babelHelpers: 'bundled',
presets: ['@babel/preset-typescript']
})
Пример:
interface User {
name: string;
}
const user: User = {
name: 'Alex'
};
После транспиляции типы удаляются.
По умолчанию Babel работает не со всеми типами файлов.
Для поддержки TypeScript и JSX часто используется настройка:
babel({
babelHelpers: 'bundled',
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx'
]
})
Полный пример:
import babel from '@rollup/plugin-babel';
export default {
input: 'src/index.tsx',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
babel({
babelHelpers: 'bundled',
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx'
]
})
]
};
Кроме пресетов Babel поддерживает большое количество отдельных плагинов.
Установка:
npm install --save-dev \
@babel/plugin-proposal-decorators
Подключение:
babel({
babelHelpers: 'bundled',
plugins: [
['@babel/plugin-proposal-decorators', {
legacy: true
}]
]
})
Плагины позволяют добавлять поддержку:
Плагин автоматически ищет:
.babelrc
или
babel.config.json
Пример:
{
"presets": [
"@babel/preset-env"
]
}
После этого конфигурация Rollup может оставаться минимальной:
babel({
babelHelpers: 'bundled'
})
Такой подход удобен для крупных проектов.
По умолчанию поиск конфигурации Babel включён.
Явное указание:
babel({
babelHelpers: 'bundled',
babelrc: true
})
Отключение:
babel({
babelHelpers: 'bundled',
babelrc: false
})
В этом случае используются только параметры из Rollup-конфигурации.
Можно указать конкретный конфигурационный файл:
babel({
babelHelpers: 'bundled',
configFile: './config/babel.config.json'
})
Это удобно для монорепозиториев и сложных корпоративных проектов.
Очень часто Babel применяется вместе с плагином разрешения модулей.
import resolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';
export default {
plugins: [
resolve(),
babel({
babelHelpers: 'bundled'
})
]
};
Порядок подключения важен.
Сначала происходит поиск модулей:
resolve()
Затем найденные файлы передаются в Babel.
Для работы со старыми пакетами:
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
export default {
plugins: [
resolve(),
commonjs(),
babel({
babelHelpers: 'bundled'
})
]
};
Типичная последовательность выглядит именно так.
Для библиотек часто применяется конфигурация:
babel({
babelHelpers: 'runtime'
})
Внешние зависимости:
export default {
external: [
/@babel\/runtime/
]
};
Такой подход позволяет уменьшить размер публикуемых пакетов.
Rollup может создавать несколько вариантов сборки.
export default {
input: 'src/index.js',
output: [
{
file: 'dist/index.esm.js',
format: 'esm'
},
{
file: 'dist/index.cjs.js',
format: 'cjs'
}
],
plugins: [
babel({
babelHelpers: 'bundled'
})
]
};
Babel выполняет транспиляцию до формирования каждого выходного файла.
На скорость работы плагина влияют:
Для ускорения сборки обычно применяются:
exclude: 'node_modules/**'
и
include: 'src/**'
Это предотвращает обработку лишних файлов.
Ошибка:
You must specify babelHelpers option
Причина:
babel()
Исправление:
babel({
babelHelpers: 'bundled'
})
Ошибка:
Cannot find module '@babel/core'
Исправление:
npm install --save-dev @babel/core
Причина:
extensions
не содержит нужные расширения.
Исправление:
extensions: [
'.js',
'.ts',
'.tsx'
]
Причина:
@babel/preset-react
не установлен либо не подключён.
Исправление:
presets: [
'@babel/preset-react'
]
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
export default {
input: 'src/index.js',
output: {
dir: 'dist',
format: 'esm',
sourcemap: true
},
plugins: [
resolve(),
commonjs(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx'
]
})
]
};
Подобная конфигурация обеспечивает корректную работу современных возможностей JavaScript, JSX и TypeScript, сохраняет преимущества модульного анализа Rollup и позволяет получать оптимизированные сборки, совместимые с широким спектром браузеров и сред выполнения.