跳至主要內容

設定 Babel

Babel 可以設定!許多其他工具有類似的設定:ESLint (.eslintrc)、Prettier (.prettierrc)。

所有 Babel API 選項都允許使用。但是,如果選項需要 JavaScript,您可能需要使用 JavaScript 設定檔

您的使用案例是什麼?

  • 您正在使用單一儲存庫嗎?
  • 您想要編譯 node_modules 嗎?

babel.config.json 適合您!

  • 您有僅適用於專案單一區塊的設定檔嗎?

.babelrc.json 適合您!

  • Guy Fieri 是您的英雄嗎?

我們建議使用 babel.config.json 格式。

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

或者,您可以選擇使用 babel 金鑰,從 package.json 內指定您的 .babelrc.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 文件 以查看更多設定選項。

您可以告訴 Babel 在指定的輸入路徑上列印有效設定


# *nix or WSL
BABEL_SHOW_CONFIG_FOR=./src/myComponent.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 會以優先順序遞增的方式列印適用的設定項目(例如 overridesenv)。通常每個設定來源至少有一個設定項目,也就是設定的根內容。如果您已設定 overridesenv,Babel 就不會在根目錄中列印它們,而是會輸出一個標題為 .overrides[index] 的個別設定項目,其中 index 是該項目的位置。這有助於確定該項目是否對輸入有效,以及它將覆寫哪些設定。

如果您的輸入被 ignoreonly 忽略,Babel 會列印此檔案已忽略。

Babel 如何合併設定項目

Babel 的設定合併相對簡單。當選項存在且其值不是 undefined 時,選項會覆寫現有的選項。不過,有幾個特殊情況

  • 對於 assumptionsparserOptsgeneratorOpts,會合併物件,而不是取代。
  • 對於 pluginspresets,它們會根據外掛程式/預設值物件/函式本身的身分,以及條目的名稱來取代。

選項(外掛程式/預設值除外)合併

舉例來說,考慮一個設定

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

NODE_ENVtest 時,sourceType 選項將被取代,而 assumptions 選項將被合併。有效設定為

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

外掛程式/預設值合併

舉例來說,考慮一個設定

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

overrides 項目將會合併至頂層選項之上。重要的是,plugins 陣列整體並不會取代頂層選項。合併邏輯會看出 "./plug" 在這兩種情況下都是同一個外掛程式,而 { thing: false, field2: true } 將會取代原始選項,產生一個設定檔如下

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

由於合併是根據識別碼 + 名稱,因此在同一個 plugins/presets 陣列中使用同一個外掛程式和同一個名稱兩次會被視為錯誤。例如

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

會被視為錯誤,因為它與 plugins: ['./plug'] 相同。此外,甚至

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

也會被視為錯誤,因為第二個只會永遠取代第一個。

如果你真的實例化外掛程式的兩個獨立實例,你必須為每個實例指定一個名稱以消除歧義。例如

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

因為每個實例都已指定一個唯一名稱,因此具有唯一的識別碼。