Babel 配置Babel

2023-06-06 16:24 更新

Babel 也有配置文件!许多其他工具都有类似的配置文件:ESLint (.eslintrc)、Prettier (.prettierrc)。

所有 Babel API 参数 都可以被配置。然而,如果该参数需要用到 JavaScript 代码,你可能需要使用 JavaScript 代码版的 配置文件


你的使用场景是什么?​

  • 你是否采用的是单一仓库(monorepo)模式?
  • 你是否需要编译 ​node_modules​?
那么 ​babel.config.json ​文件可以满足你的的需求!
  • 你的配置文件是否仅适用于项目的某个部分?
那么 ​.babelrc.json​ 文件适合你!
  • Guy Fieri 是你崇拜的对象?
我们建议使用​ babel.config.json ​格式的配置文件。  Babel 自身使用的就是这种格式

babel.config.json​

在项目的根目录(package.json 文件所在的目录)下创建一个名为 babel.config.json 的文件,并输入如下内容。

babel.config.json

{
"presets": [...],
"plugins": [...]
}

请参阅 babel.config.json 文档 以了解更多关于配置参数的信息。

.babelrc.json

在你的项目中创建名为 .babelrc.json 的文件,并输入以下内容。

.babelrc.json

{
"presets": [...],
"plugins": [...]
}

请参阅 .babelrc 文档 以了解更多关于配置参数的信息。

package.json

或者,还可以选择将 .babelrc.json 中的配置信息作为 babel 键(key)的值添加到 package.json 文件中,如下所示:

package.json

{
"name": "my-package",
"version": "1.0.0",
"babel": {
"presets": [ ... ],
"plugins": [ ... ],
}
}

用 JavaScript 编写配置文件

你还可以用 JavaScript 来编写 babel.config.js 和 .babelrc.js 文件:

babel.config.js

module.exports = function (api) {
api.cache(true);

const presets = [ ... ];
const plugins = [ ... ];

return {
presets,
plugins
};
}

你还可以调用 Node.js 的任何 API,例如基于进程环境进行动态配置:

babel.config.js

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)

Shell

babel --plugins @babel/plugin-transform-arrow-functions script.js

请参阅 babel-cli 文档 以了解更多关于配置参数的信息。

使用 API (@babel/core)

JavaScript

require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-arrow-functions"],
});

请参阅 babel-core 文档 以了解更多关于配置参数的信息。

Print effective configs

You can tell Babel to print effective configs on a given input path

  • Shell
  • powershell

# *nix or WSL
BABEL_SHOW_CONFIG_FOR=./src/myComponent.jsx npm start

BABEL_SHOW_CONFIG_FOR accepts both absolute and relative file paths. If it is a relative path, it will be resolved from cwd.

Once Babel processes the input file specified by BABEL_SHOW_CONFIG_FOR, Babel will print effective configs to the console. Here is an example output:

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 will print effective config sources ordered by ascending priority. Using the example above, the priority is:

babel.config.json < .babelrc < programmatic options from @babel/cli

In other words, babel.config.json is overwritten by .babelrc, and .babelrc is overwritten by programmatic options.

For each config source, Babel prints applicable config items (e.g. overrides and env) in the order of ascending priority. Generally each config sources has at least one config item -- the root content of configs. If you have configured overrides or env, Babel will not print them in the root, but will instead output a separate config item titled as .overrides[index], where index is the position of the item. This helps determine whether the item is effective on the input and which configs it will override.

If your input is ignored by ignore or only, Babel will print that this file is ignored.

How Babel merges config items

Babel's configuration merging is relatively straightforward. Options will overwrite existing options when they are present and their value is not undefined. There are, however, a few special cases:

  • For assumptions, parserOpts and generatorOpts, objects are merged, rather than replaced.
  • For plugins and presets, they are replaced based on the identity of the plugin/preset object/function itself combined with the name of the entry.

Option (except plugin/preset) merging

As an example, consider a config with:

JavaScript

{
sourceType: "script",
assumptions: {
setClassFields: true,
iterableIsArray: false
},
env: {
test: {
sourceType: "module",
assumptions: {
iterableIsArray: true,
},
}
}
};

When NODE_ENV is test, the sourceType option will be replaced and the assumptions option will be merged. The effective config is:

JavaScript

{
sourceType: "module", // sourceType: "script" is overwritten
assumptions: {
setClassFields: true,
iterableIsArray: true, // assumptions are merged by Object.assign
},
}

Plugin/Preset merging

As an example, consider a config with:

JavaScript

plugins: [
'./other',
['./plug', { thing: true, field1: true }]
],
overrides: [{
plugins: [
['./plug', { thing: false, field2: true }],
]
}]

The overrides item will be merged on top of the top-level options. Importantly, the plugins array as a whole doesn't just replace the top-level one. The merging logic will see that "./plug" is the same plugin in both cases, and { thing: false, field2: true } will replace the original options, resulting in a config as

JavaScript

plugins: [
'./other',
['./plug', { thing: false, field2: true }],
],

Since merging is based on identity + name, it is considered an error to use the same plugin with the same name twice in the same plugins/presets array. For example

JavaScript

plugins: ["./plug", "./plug"];

is considered an error, because it's identical to plugins: ['./plug']. Additionally, even

JavaScript

plugins: [["./plug", { one: true }], ["./plug", { two: true }]];

is considered an error, because the second one would just always replace the first one.

If you actually do want to instantiate two separate instances of a plugin, you must assign each one a name to disambiguate them. For example:

JavaScript

plugins: [
["./plug", { one: true }, "first-instance-name"],
["./plug", { two: true }, "second-instance-name"],
];

because each instance has been given a unique name and thus a unique identity.


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号