Файлы конфигурации
Типы файлов конфигурации
Babel имеет два параллельных формата файлов конфигурации, которые можно использовать вместе или независимо.
История
| Версия | Изменения |
|---|---|
v7.21.0 |
Поддержка .babelrc.cts и babel.config.cts (Экспериментальная) |
v7.8.0 |
Поддержка .babelrc.mjs и babel.config.mjs
|
v7.7.0 |
Поддержка .babelrc.json, .babelrc.cjs, babel.config.json, babel.config.cjs
|
- Конфигурация для всего проекта
-
babel.config.*файлы с расширениями:.json,.js,.cjs,.mjs,.cts.
-
- Конфигурация, относящаяся к файлам
-
.babelrc.*файлы с расширениями:.json,.js,.cjs,.mjs,.cts. -
.babelrcфайл без расширения. -
package.jsonфайлы с ключом"babel".
-
Конфигурация для всего проекта
В Babel 7.x добавлено понятие директории "корень", которая по умолчанию совпадает с текущей рабочей директорией. Для конфигурации всего проекта Babel автоматически ищет файл babel.config.json или эквивалентный ему файл с поддерживаемым расширением в этой корневой директории. В качестве альтернативы пользователи могут использовать явное значение "configFile" для переопределения поведения поиска файла конфигурации по умолчанию.
Поскольку файлы конфигурации всего проекта отделены от физического расположения файла конфигурации, они идеально подходят для конфигурации, которая должна применяться широко, даже позволяя плагинам и пресетам легко применяться к файлам в node_modules или в пакетах со символическими ссылками, что традиционно было довольно сложным в конфигурации в Babel 6.x.
Основным недостатком этой конфигурации для всего проекта является то, что, поскольку она полагается на рабочую директорию, её использование в монорепозиториях может быть более затруднительным, если рабочая директория не является корнем монорепозитория. См. документацию по монорепозиториям для примеров использования файлов конфигурации в этом контексте.
Конфигурацию для всего проекта также можно отключить, установив "configFile" в значение false.
Конфигурация, относящаяся к файлам
Babel загружает .babelrc.json файлы или эквивалентные файлы с использованием поддерживаемых расширений, выполняя поиск по структуре каталогов, начиная от компилируемого "filename" (с ограничениями, указанными ниже). Это может быть мощно, поскольку позволяет создавать независимые конфигурации для подмножеств пакета. Конфигурации, относящиеся к файлам, также сливаются поверх значений конфигурации для всего проекта, что делает их потенциально полезными для конкретных переопределений, хотя это также можно сделать с помощью "overrides".
Существует несколько граничных случаев, которые необходимо учитывать при использовании конфигурации, относящейся к файлам:
- Поиск прекратится, как только будет найден каталог, содержащий
package.json, поэтому относительная конфигурация применяется только внутри одного пакета. - "filename" для компиляции должен находиться внутри пакетов в "babelrcRoots", иначе поиск будет пропущен полностью.
Эти ограничения означают, что:
-
.babelrc.jsonфайлы только применяются к файлам внутри своего собственного пакета -
.babelrc.jsonфайлы в пакетах, которые не являются 'корнем' Babel, игнорируются, если вы не включите поддержку с помощью "babelrcRoots".
См. документацию по монорепозиториям для получения дополнительной информации о том, как настроить монорепозитории с множеством пакетов. Конфигурацию, относящуюся к файлам, также можно отключить, установив "babelrc" в значение false.
Загрузка .babelrc в Babel 6.x и 7.x
Пользователи, переходящие с Babel 6.x, могут столкнуться с этими двумя граничными случаями, которые являются новыми в Babel 7.x. Эти два ограничения были добавлены для устранения распространенных проблем в Babel 6.x:
-
.babelrcфайлы применялись кnode_modulesзависимостям, часто неожиданно. -
.babelrcфайлы не применялись к зависимостям со символическими ссылкамиnode_modules, когда ожидалось, что они будут вести себя как обычные зависимости. -
.babelrcфайлы вnode_modulesзависимостях обнаруживались, даже если плагины и пресеты внутри них обычно не были установлены, и могут даже быть неверны в версии Babel, компилирующей файл.
Эти случаи в основном вызывают проблемы для пользователей с монорепозиторной структурой, потому что, если у вас есть
.babelrc
packages/
mod1/
package.json
src/index.js
mod2/
package.json
src/index.js
конфигурация теперь будет полностью проигнорирована, так как она находится за пределами пакета.
Одним из вариантов является создание .babelrc в каждом подпакете, который использует "extends" как
{ "extends": "../../.babelrc" }
К сожалению, этот подход может быть несколько повторяющимся, и в зависимости от того, как используется Babel, может потребоваться установить "babelrcRoots".
Учитывая это, может быть более желательно переименовать .babelrc в файл конфигурации проекта "babel.config.json". Как упоминалось в разделе о конфигурации для всего проекта, это может потребовать явного задания "configFile", так как Babel не найдет файл конфигурации, если рабочая директория не является правильной.
Поддерживаемые расширения файлов
Babel может настраиваться с помощью любого расширения файла, которое изначально поддерживается Node.js, как упоминается в разделе Типы файлов конфигурации:
-
babel.config.jsonи.babelrc.jsonобрабатываются как JSON5 и должны содержать объект, соответствующий формату параметров, которые принимает Babel. Они поддерживаются сv7.7.0.Мы рекомендуем использовать этот тип файлов везде, где это возможно: файлы конфигурации JS полезны, если у вас сложная конфигурация, которая зависит от условных условий или вычисляется во время сборки. Однако недостатком является то, что конфигурации JS менее статически анализируются и, следовательно, оказывают негативное влияние на кешируемость, проверку кода, автодополнение в IDE и т. д. Поскольку
babel.config.jsonи.babelrc.jsonявляются статическими файлами JSON, это позволяет другим инструментам, использующим Babel, таким как сборщики, безопасно кэшировать результаты Babel, что может значительно ускорить сборку. babel.config.cjsи.babelrc.cjsпозволяют определить конфигурацию как CommonJS, используяmodule.exports. Они поддерживаются сv7.7.0.babel.config.mjsи.babelrc.mjsиспользуют собственные модули ECMAScript. Они поддерживаются Node.js 13.2+ (или более старыми версиями с помощью флага--experimental-modules). Помните, что собственные модули ECMAScript асинхронны (поэтомуimport()всегда возвращает промис!): по этой причине файлы конфигурации.mjsбудут вызывать ошибку при вызове Babel синхронно. Они поддерживаются сv7.8.0.babel.config.jsи.babelrc.jsведут себя как эквиваленты.mjs, когда ваш файлpackage.jsonсодержит параметр"type": "module", в противном случае они точно такие же, как файлы.cjs.-
babel.config.ctsи.babelrc.ctsпозволяют определить конфигурацию как Typescript + CommonJS. Вам необходимо установить@babel/preset-typescript, или запустить Babel с флагомts-node.🚧 Эта функциональность экспериментальная. Пока нельзя использовать файлы
babel.config.tsиbabel.config.mts, ожидается стабилизация API загрузчика модулей Node.js ESM.
Файлы конфигурации JavaScript могут экспортировать объект или функцию, которая при вызове возвращает сгенерированную конфигурацию. Конфигурации, возвращающие функции, получают несколько особых возможностей, потому что они могут получить доступ к API, предоставляемому самим Babel. См. API функций конфигурации для получения дополнительной информации.
По соображениям совместимости,
.babelrcявляется псевдонимом для.babelrc.json.
Монорепозитории
Монорепозиторные репозитории обычно содержат множество пакетов, что означает, что они часто сталкиваются с проблемами, упомянутыми в разделе конфигурации, относящейся к файлам, и с загрузкой файлов конфигурации в целом. Этот раздел призван помочь пользователям понять, как подходить к конфигурации монорепозитория.
В монорепозиторных установках ключевым моментом является то, что Babel рассматривает вашу рабочую директорию как логический "корень", что создает проблемы, если вы хотите запустить инструменты Babel в определенном подпакете, не заставляя Babel применять их ко всему репозиторию.
Кроме того, важно решить, хотите ли вы использовать файлы .babelrc.json или только центральный файл babel.config.json. Файлы .babelrc.json не требуются для конфигурации, специфичной для подкаталогов, как это было в Babel 6, поэтому в Babel 7 они часто не нужны в пользу babel.config.json.
Файл babel.config.json в корне
Первым шагом в любой структуре монорепозитория должно быть создание файла babel.config.json в корне репозитория. Это устанавливает основное понятие Babel о базовой директории вашего репозитория. Даже если вы хотите использовать файлы .babelrc.json для конфигурации каждого отдельного пакета, важно иметь место для параметров уровня репозитория.
Вы часто можете разместить всю конфигурацию вашего репозитория в корневом babel.config.json. С помощью "переопределений" вы можете легко указать конфигурацию, которая применяется только к определённым подпапкам вашего репозитория, что часто проще, чем создание множества .babelrc.json файлов по всему репозиторию.
Первая проблема, с которой вы, вероятно, столкнётесь, заключается в том, что по умолчанию Babel ожидает загрузки babel.config.json файлов из каталога, установленного в качестве своего "корня", что означает, что если вы создаёте babel.config.json, но запускаете Babel внутри отдельного пакета, например:
cd packages/some-package; babel src -d dist
корень, используемый Babel в этом контексте, не является корнем вашего монорепозитория, и он не сможет найти файл babel.config.json.
Если все ваши скрипты сборки выполняются относительно корня вашего репозитория, всё должно работать, но если вы запускаете процесс компиляции Babel из подпакета, вам нужно указать Babel, где искать конфигурацию. Есть несколько способов сделать это, но рекомендуемый способ — опция "rootMode" со значением "upward", которая заставит Babel искать файл вашей конфигурации babel.config.json вверх от текущей рабочей директории и использовать его расположение как значение "корня".
Полезным способом проверки того, что ваша конфигурация обнаружена, является размещение вызова console.log() внутри него, если это babel.config.json файл JavaScript: лог будет выполнен в первый раз при загрузке Babel.
Способ установки этого значения зависит от проекта, но вот несколько примеров:
CLI
babel --root-mode upward src -d lib
@babel/register
require("@babel/register")({
rootMode: "upward",
});
Webpack
module: {
rules: [
{
loader: "babel-loader",
options: {
rootMode: "upward",
},
},
];
}
Jest
Jest часто устанавливается в корне монорепозитория и может не потребовать конфигурации, но если он установлен на каждый пакет, его конфигурация может быть более сложной.
Основной частью является создание настраиваемого файла преобразующего Jest, который оборачивает поведение по умолчанию babel-jest для установки опции, например:
module.exports = require("babel-jest").default.createTransformer({
rootMode: "upward",
});
и, сохранив его где-нибудь, вы затем используете этот файл вместо babel-jest в ваших настройках Jest через опцию transform:
"transform": {
"^.+\\.jsx?$": "./path/to/wrapper.js"
},
Таким образом, все файлы JS будут обрабатываться вашей версией babel-jest с включённой опцией.
ПРИМЕЧАНИЕ: При использовании
babel-jest< 27, вы должны опустить часть.default:require("babel-jest").createTransformer({ ...
Другие
Существует множество инструментов, но в основе их работы лежит необходимость включения опции rootMode, если рабочая директория не является корнем монорепозитория.
Файлы подпакета .babelrc.json
Аналогично тому, как файлы babel.config.json должны находиться в "корне", файлы .babelrc.json по умолчанию должны находиться в корневом пакете. Это означает, что, так же как рабочая директория влияет на загрузку babel.config.json, она также влияет на загрузку .babelrc.json.
Предполагая, что вы уже правильно загрузили файл babel.config.json, как описано выше, Babel будет обрабатывать только файлы .babelrc.json внутри этого корневого пакета (а не подпакетов), поэтому, например,
package.json
babel.config.js
packages/
mod/
package.json
.babelrc.json
index.js
компиляция файла packages/mod/index.js не загрузит packages/mod/.babelrc.json, потому что этот .babelrc.json находится в подпакете, а не в корневом пакете.
Чтобы включить обработку этого .babelrc.json, вам нужно использовать опцию "babelrcRoots" внутри вашего файла babel.config.json для:
babelrcRoots: [ ".", "packages/*", ],
чтобы Babel рассматривал все packages/* пакеты как разрешённые для загрузки файлов .babelrc.json, наряду с исходным корнем репозитория.
API Функции конфигурации
Файлы конфигурации JS могут экспортировать функцию, которой будет передан API функции конфигурации:
module.exports = function(api) {
return {};
};
Объект api предоставляет всё, что Babel предоставляет сам из своего модуля index, а также API, специфичные для файла конфигурации:
api.version
Тип: %%%CODE_BLOCK_122%%>
Строка версии Babel, которая загружает файл конфигурации.
api.cache
JS конфигурации отличны тем, что они могут вычислять конфигурацию на лету, но недостатком является то, что кэширование становится сложнее. Babel хочет избежать повторного выполнения функции конфигурации каждый раз при компиляции файла, поскольку это также потребует повторного выполнения любых функций плагинов и пресетов, упомянутых в этой конфигурации.
Чтобы этого избежать, Babel ожидает, что пользователи функций конфигурации сообщат ему, как управлять кэшированием в файле конфигурации.
-
api.cache.forever()— Постоянно кэшировать вычисленную конфигурацию и больше никогда не вызывать функцию. -
api.cache.never()— Не кэшировать эту конфигурацию и каждый раз перевыполнять функцию. -
api.cache.using(() => process.env.NODE_ENV)— Кэшировать на основе значенияNODE_ENV. Всякий раз, когда обратный вызовusingвозвращает значение, отличное от ожидаемого, общая функция конфигурации будет вызвана снова, и новая запись будет добавлена в кэш. -
api.cache.invalidate(() => process.env.NODE_ENV)— Кэшировать на основе значенияNODE_ENV. Всякий раз, когда обратный вызовusingвозвращает значение, отличное от ожидаемого, общая функция конфигурации будет вызвана снова, и все записи в кэше будут заменены результатом. -
api.cache(true)— То же, что иapi.cache.forever() -
api.cache(false)— То же, что иapi.cache.never()
Поскольку фактический результат обратного вызова используется для проверки того, является ли запись в кэше действительной, рекомендуется:
- Обратные вызовы должны быть небольшими и не иметь побочных эффектов.
- Обратные вызовы должны возвращать значения с наименьшим возможным диапазоном. Например, использование
.using(() => process.env.NODE_ENV)выше не является идеальным, потому что оно создаст неизвестное количество записей в кэше, в зависимости от того, сколько значенийNODE_ENVбудет обнаружено. Безопаснее сделать.using(() => process.env.NODE_ENV === "development"), так как тогда запись в кэше может быть толькоtrueилиfalse.
api.env(...)
Поскольку NODE_ENV является достаточно распространённым способом изменения поведения, Babel также включает API-функцию, специально предназначенную для этого. Этот API используется как быстрый способ проверки "имени среды", с которым был загружен Babel, который учитывает NODE_ENV, если не установлена другая переопределяющая среда.
Он имеет несколько форм:
-
api.env("production")возвращаетtrue, еслиenvName === "production". -
api.env(["development", "test"])возвращаетtrue, если["development", "test"].includes(envName). -
api.env()возвращает текущую строкуenvName. -
api.env(envName => envName.startsWith("test-"))возвращаетtrue, если среда начинается с "test-".
Примечание: Эта функция внутренне использует
api.cache, упомянутую выше, чтобы убедиться, что Babel знает, что эта сборка зависит от определённойenvName. Вы не должны использовать её вместе сapi.cache.forever()илиapi.cache.never().
api.caller(cb)
Этот API используется для доступа к данным caller, переданными Babel. Поскольку несколько экземпляров Babel могут выполняться в одном процессе с различными значениями caller, этот API предназначен для автоматической настройки api.cache, так же как и api.env().
Значение caller доступно в качестве первого параметра функции обратного вызова. Лучше всего использовать его с чем-то вроде
function isBabelRegister(caller) {
return !!(caller && caller.name === "@babel/register");
}
module.exports = function(api) {
const isRegister = api.caller(isBabelRegister);
return {
// ...
};
};
для изменения поведения конфигурации на основе определённой среды.
api.assertVersion(range)
Хотя api.version может быть полезным в общем случае, иногда удобно просто объявить свою версию. Этот API предоставляет простой способ сделать это с помощью:
module.exports = function(api) {
api.assertVersion("^7.2");
return {
// ...
};
};
© 2014-present Sebastian McKenzie
Licensed under the MIT License.
https://babeljs.io/docs/config-files/