配置 Babel
Babel 可以配置!许多其他工具也有类似的配置文件:ESLint (.eslintrc
)、Prettier (.prettierrc
)。
所有 Babel API 选项 都可用。但是,如果该选项需要 JavaScript,您可能需要使用 JavaScript 配置文件。
您的用例是什么?
- 您正在使用 monorepo 吗?
- 您想编译
node_modules
吗?
babel.config.json
适合您!
- 您是否有一个仅适用于项目一部分的配置?
.babelrc.json
适合您!
- Guy Fieri 是您的偶像吗?
我们建议使用
babel.config.json
格式。
babel.config.json
在项目的根目录(package.json
所在的位置)创建一个名为 babel.config.json
的文件,内容如下。
{
"presets": [...],
"plugins": [...]
}
查看 babel.config.json
文档 以了解更多配置选项。
.babelrc.json
在您的项目中创建一个名为 .babelrc.json
的文件,内容如下。
{
"presets": [...],
"plugins": [...]
}
查看 .babelrc 文档 以了解更多配置选项。
package.json
或者,您可以选择在 package.json
中使用 babel
键指定您的 .babelrc.json
配置,如下所示
{
"name": "my-package",
"version": "1.0.0",
"babel": {
"presets": [ ... ],
"plugins": [ ... ],
}
}
JavaScript 配置文件
您也可以使用 JavaScript 编写 babel.config.js
(就像我们正在做的那样)和 .babelrc.js
文件
module.exports = function (api) {
api.cache(true);
const presets = [ ... ];
const plugins = [ ... ];
return {
presets,
plugins
};
}
您可以访问任何 Node.js API,例如基于进程环境的动态配置
module.exports = function (api) {
api.cache(true);
const presets = [ ... ];
const plugins = [ ... ];
if (process.env["ENV"] === "prod") {
plugins.push(...);
}
return {
presets,
plugins
};
}
您可以在 专用文档 中阅读有关 JavaScript 配置文件的更多信息
使用 CLI (@babel/cli
)
babel --plugins @babel/plugin-transform-arrow-functions script.js
查看 babel-cli 文档 以了解更多配置选项。
使用 API (@babel/core
)
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-arrow-functions"],
});
查看 babel-core 文档 以了解更多配置选项。
打印有效配置
您可以告诉 Babel 在给定的输入路径上打印有效配置
- Shell
- powershell
# *nix or WSL
BABEL_SHOW_CONFIG_FOR=./src/myComponent.jsx npm start
$env:BABEL_SHOW_CONFIG_FOR = ".srcmyComponent.jsx"; npm start
BABEL_SHOW_CONFIG_FOR
接受绝对和相对的*文件*路径。如果是相对路径,它将从 cwd
解析。
一旦 Babel 处理了 BABEL_SHOW_CONFIG_FOR
指定的输入文件,Babel 就会将有效配置打印到控制台。以下是一个输出示例
Babel configs on "/path/to/cwd/src/index.js" (ascending priority):
config /path/to/cwd/babel.config.json
{
"sourceType": "script",
"plugins": [
"@foo/babel-plugin-1"
],
"extends": "./my-extended.js"
}
config /path/to/cwd/babel.config.json .env["test"]
{
"plugins": [
[
"@foo/babel-plugin-3",
{
"noDocumentAll": true
},
]
]
}
config /path/to/cwd/babel.config.json .overrides[0]
{
"test": "src/index.js",
"sourceMaps": true
}
config /path/to/cwd/.babelrc
{}
programmatic options from @babel/cli
{
"sourceFileName": "./src/index.js",
"presets": [
"@babel/preset-env"
],
"configFile": "./my-config.js",
"caller": {
"name": "@babel/cli"
},
"filename": "./src/index.js"
}
Babel 将按优先级升序打印有效的配置源。使用上面的示例,优先级为
babel.config.json < .babelrc < programmatic options from @babel/cli
换句话说,babel.config.json
被 .babelrc
覆盖,而 .babelrc
被编程选项覆盖。
对于每个配置源,Babel 会按优先级升序打印适用的配置项(例如 overrides
和 env
)。通常,每个配置源至少有一个配置项——配置的根内容。如果您配置了 overrides
或 env
,Babel 不会在根目录中打印它们,而是输出一个单独的配置项,标题为 .overrides[index]
,其中 index
是该项的位置。这有助于确定该项是否对输入有效以及它将覆盖哪些配置。
如果您的输入被 ignore
或 only
忽略,Babel 将打印该文件被忽略。
Babel 如何合并配置项
Babel 的配置合并相对简单。当选项存在且其值不为 undefined
时,它们将覆盖现有选项。但是,有一些特殊情况
- 对于
assumptions
、parserOpts
和generatorOpts
,对象是合并的,而不是替换的。 - 对于
plugins
和presets
,它们根据插件/预设对象/函数本身的身份以及条目的名称进行替换。
选项(插件/预设除外)合并
例如,考虑一个具有以下内容的配置
{
sourceType: "script",
assumptions: {
setClassFields: true,
iterableIsArray: false
},
env: {
test: {
sourceType: "module",
assumptions: {
iterableIsArray: true,
},
}
}
};
当 NODE_ENV
为 test
时,sourceType
选项将被替换,assumptions
选项将被合并。有效配置为
{
sourceType: "module", // sourceType: "script" is overwritten
assumptions: {
setClassFields: true,
iterableIsArray: true, // assumptions are merged by Object.assign
},
}
插件/预设合并
例如,考虑一个具有以下内容的配置
plugins: [
'./other',
['./plug', { thing: true, field1: true }]
],
overrides: [{
plugins: [
['./plug', { thing: false, field2: true }],
]
}]
overrides
项将合并到顶级选项之上。重要的是,整个 plugins
数组不会仅仅替换顶级数组。合并逻辑将看到 "./plug"
在两种情况下都是同一个插件,并且 { thing: false, field2: true }
将替换原始选项,从而生成如下配置
plugins: [
'./other',
['./plug', { thing: false, field2: true }],
],
由于合并是基于身份+名称的,因此在同一个 plugins
/presets
数组中两次使用相同名称的相同插件被认为是错误的。例如
plugins: ["./plug", "./plug"];
被认为是错误的,因为它与 plugins: ['./plug']
相同。此外,即使是
plugins: [["./plug", { one: true }], ["./plug", { two: true }]];
也被认为是错误的,因为第二个总是会替换第一个。
如果您确实*想*实例化一个插件的两个独立实例,则必须为每个实例分配一个名称以区分它们。例如
plugins: [
["./plug", { one: true }, "first-instance-name"],
["./plug", { two: true }, "second-instance-name"],
];
因为每个实例都被赋予了唯一的名称,因此具有唯一的身份。