跳到主要內容

升級到 Babel 7(API)

升級到 Babel 7 時,請將使用者轉介至本文件。

另請參閱 v7-migration 指南,了解其他使用者層級變更。

所有 Babel 套件

NodeJS 支援

high

已移除對 Node.js 0.10 和 0.12 的支援,因為這兩個版本已停止維護。

匯出變更

medium

已放棄在 Babel 套件上使用 add-module-exports 外掛程式。之前必須使用它來避免我們的匯出發生重大變更。如果你在函式庫中匯入 Babel 套件,在使用 require 而不是 import 時,你可能需要使用 .default

@babel/core

已將 ast 預設變更為 false 以提升效能(大多數工具並未使用它)babel/babel#7436

已移除公開公開但未記載的 Pipeline 類別。最好直接使用 @babel/core 公開的轉換方法babel/babel#5376

已移除 babel.util.* 輔助方法,且 util.EXTENSIONS 已移至 babel.DEFAULT_EXTENSIONSbabel/babel#5487

如果檔案符合 ignore 模式或無法符合 only 模式,呼叫 babel.transform 或任何其他轉換函式可能會傳回 nullbabel/babel#5487

已移除 state.file.opts 上公開的 opts.basename 選項。如果你需要它,最好自行從 opts.filename 建立它babel/babel#5467

已移除 resolveModuleSource。我們建議使用 babel-plugin-module-resolver@3 的「resolvePath」選項babel/babel#6343

移除 babel.analyse,因為它只是 babel.transform 的別名

移除 path.mark(),因為我們沒有使用它,而且它可以在您自己的外掛程式中實作。

移除 babel.metadata,因為產生的外掛程式元資料總是包含在輸出結果中。

移除 path.hub.file.addImport。您可以改用 @babel/helper-module-imports 模組。

+  import { addDefault } from "@babel/helper-module-imports";
function importModule(pkgStore, name, path) {
- return path.hub.file.addImport(resolvePath(pkgStore, name, path), 'default', name);
+ return addDefault(path, resolvePath(pkgStore, name, path), { nameHint: name });
}

設定檔變更

我們對設定檔查詢方式進行了一些重大變更

預設情況下,當為特定檔案搜尋 .babelrc 檔案時,會在 package.json 停止。

對於任何特定檔案,Babel v6 會持續查詢目錄階層,直到找到設定檔。這表示您的專案可能會中斷,因為它使用在套件根目錄外部找到的設定檔,例如在主目錄中。

新增支援 babel.config.js 檔案,類似於 Webpack 的作法

由於這會中斷單一存放庫的運作方式(包括 Babel 本身),我們正在引入一個新的設定檔,基本上可以移除設定檔的階層性質。

其中包含一個 root 選項,預設為目前的作業目錄,以便它找到檔案。它也不是相對載入的,因此它會正確處理符號連結,而之前您可能必須在 webpack 中硬式編碼路徑。

查看 babel.config.js 文件以取得更多資訊:專案範圍設定檔

此檔案與新的 overrides 屬性和 env 結合使用,讓您擁有單一設定檔,可適用於專案中的所有檔案,而非每個資料夾使用多個設定檔。

我們預設會排除 node_modules,而且只會在根目錄中尋找,除非您選擇設定 .babelrcRoots 選項的陣列,例如 "babelrcRoots": [".", "node_modules/pkgA"]

宣告 Babel 版本 #7450

外掛可以檢查是否已載入特定版本的 Babel。此 API 將公開一個 assertVersion 方法,您可以在其中傳入 semver。

宣告輔助函式用於維持與 v6 的向下相容性。

JavaScript
import { declare } from "@babel/helper-plugin-utils";

export default declare(api => {
api.assertVersion(7);
// ...
});

Babel 外掛/預設值

它目前將 babel 物件、外掛/預設值選項和 dirname 視為第一個參數

JavaScript
module.exports = function(api, options, dirname) {};

babel-parser(稱為 Babylon)

移除 * 外掛選項 #301 low

這最初新增於 v6.14.1(2016 年 11 月 17 日),因此不太可能有人使用此功能。

已移除此萬用選項;您應明確決定要啟用的外掛程式。

我們認為這對工具來說是個好主意,這樣它們就不必持續更新其設定檔,但也表示我們無法輕易進行重大變更。

之前

JavaScript
babelParser.parse(code, {
plugins: ["*"],
});

您可以使用下列方式取得舊有行為

JavaScript
babelParser.parse(code, {
plugins: [
"asyncGenerators",
"classProperties",
"decorators",
"doExpressions",
"dynamicImport",
"exportExtensions",
"flow",
"functionBind",
"functionSent",
"jsx",
"objectRestSpread",
],
});

請參閱 Babylon 的外掛程式選項

decorators外掛程式重新命名為decorators-legacy medium

已重新命名,以符合@babel/plugin-proposal-decoratorslegacy選項。已實作新的decorators外掛程式,實作新的裝飾器提案。

這兩個版本提案的語法不同,因此強烈建議使用decorators-legacy,直到 Babel 實作新的語意。

已移除classConstructorCall外掛程式 #291 low

@babel/traverse

移除對 flow 繫結的支援 babel/babel#6528

此變更背後的原因是declare var foo不會引入新的區域繫結,但它代表一個全域繫結。

getFunctionParent不再會傳回Program,請改用getProgramParent #5923. low

名為getFunctionParent的函式傳回 Program 沒有意義,因此已移除。

若要取得等效行為,您需要進行類似變更

- path.scope.getFunctionParent()
+ path.scope.getFunctionParent() || path.scope.getProgramParent()

路徑替換/移除 API 現在會傳回新的路徑陣列 low

例如,使用 Path#insertBeforePath#replaceWith 現在會永遠傳回新插入/替換路徑的陣列。

JavaScript
const node = t.nullLiteral();
const [replaced] = path.replaceWith(node);
replace.node === node; // => true

這在將數個節點插入較高層級範圍時特別有用,因為您可以立即在節點的新 Path 上呼叫 Path API。

JavaScript
const parent = path.findParent(() => /* some selection criteria */);
const helperPaths = path.unshiftContainer("body", helpers);
// helperPaths can now be referenced, manipulated, etc.

AST 變更

新增 InterpreterDirective 節點 #7928

Babylon 已剖析「shebangs」(#!env node),但會在 Program 節點中放入註解。現在我們只會為其建立實際節點。

新增新的 interpreter 欄位至 Program 節點。

JavaScript
extend interface Program {
interpreter: InterpreterDirective;
}

新增 InterpreterDirective 節點

JavaScript
interface InterpreterDirective <: Node {
type: "InterpreterDirective";
value: string;
}

JSX* 和 TS* 節點建構器 (來自 @babel/types 套件) 已重新命名

大小寫已變更:jsxts 現在是小寫。

- t.jSXIdentifier()
+ t.jsxIdentifier()

一般來說,我們已針對 Flow 的 TypeAnnotation 和 TypeScript 的 TSTypeAnnotation 區分節點類型,因此對於共用類型節點,TypeScript 會有 TS 前綴。

已移除 ArrowFunctionExpression.expression 欄位

已移除 expression 欄位,以消除兩個不同的真實來源,並讓外掛程式不再需要手動將它們保持同步。現在您可以簡單地檢查函式主體是否為 BlockStatement

  return {
visitor: {
ArrowFunctionExpression({ node }) {
- if (node.expression) {
+ if (node.body.type !== "BlockStatement") {
// () => foo;
}
}
}
};

已移除的 Token

在先前的版本中,tokens 始終附加至頂層的 AST。在最新版本的 @babel/parser 中,我們已移除此行為,並將其預設為停用,以提升解析器的效能。babel 中的所有用法均已移除,且 @babel/generator 不再使用 token 進行美化列印。

如果你的 babel 外掛目前使用 tokens,請評估是否仍有必要,並盡可能嘗試移除用法。如果你的外掛真的仰賴取得 token,你可以重新啟用它,但請僅在別無他法時考慮這麼做,因為這會影響使用者的效能。

若要啟用,你需要將 babylon 的 tokens 選項設為 true。你可以直接從你的外掛執行此動作。

JavaScript
export default function() {
return {
manipulateOptions(opts, parserOpts) {
parserOpts.tokens = true;
},
...
};
}

已重新命名

下列節點已重新命名

6.x 名稱7.x 名稱範例PR
ExistentialTypeParamExistsTypeAnnotationtype A = B<*>;#322
NumericLiteralTypeAnnotationNumberLiteralTypeAnnotationtype T = 0;#332

除了 AST 節點之外,@babel/types 中所有對應的函式也已重新命名。

 import * as t from "@babel/types";

return {
- ExistentialTypeParam(path) {
- const parent = path.findParent((path) => path.isExistentialTypeParam());
- t.isExistentialTypeParam(parent);
+ ExistsTypeAnnotation(path) {
+ const parent = path.findParent((path) => path.isExistsTypeAnnotation());
+ t.isExistsTypeAnnotation(parent);

- return t.existentialTypeParam();
+ return t.existsTypeAnnotation();
},
- NumericLiteralTypeAnnotation(path) {
- const parent = path.findParent((path) => path.isNumericLiteralTypeAnnotation());
- t.isNumericLiteralTypeAnnotation(parent);
+ NumberLiteralTypeAnnotation(path) {
+ const parent = path.findParent((path) => path.isNumberLiteralTypeAnnotation());
+ t.isNumberLiteralTypeAnnotation(parent);

- return t.numericLiteralTypeAnnotation();
+ return t.numberLiteralTypeAnnotation();
}
};

已取代

在下列 AST 節點中,variance 欄位的數值已從單純的字串值變更為稱為 Variance 的 AST 節點本身。 #333

當在 babylon 中啟用 flow 外掛時,此欄位才可用。

  • ObjectProperty
  • ObjectMethod
  • AssignmentProperty
  • ClassMethod
  • ClassProperty
  • Property

新的 Variance 節點類型看起來像這樣

JavaScript
type VarianceNode = {
type: "Variance",
kind: "plus" | "minus",
};
 return {
Property({ node }) {
- if (node.variance === "plus") {
+ if (node.variance.kind === "plus") {
...
- } else if (node.variance === "minus") {
+ } else if (node.variance.kind === "minus") {
...
}
}
};

位置變更

ObjectTypeIndexer 的位置資訊已變更,不包含分號。此變更與 flow-parser 保持一致,並具有相同的位置資訊。 #228

範例

JavaScript
var a: { [a: number]: string };
 {
"type": "ObjectTypeIndexer",
"start": 9,
- "end": 29,
+ "end": 28,
"loc": {
"start": {
"line": 1,
"column": 9,
},
"end": {
"line": 1,
- "column": 29
+ "column": 28
}
}
}

移除

ForAwaitStatement

AST 節點 ForAwaitStatement 已移除,並以 ForOfStatement 節點中的 await 欄位取代 #349

 interface ForOfStatement <: ForInStatement {
type: "ForOfStatement";
+ await: boolean;
}
 return {
- ForAwaitStatement(path) {
- ...
+ ForOfStatement(path) {
+ if (path.node.await) {
+ ...
+ }
}
};

RestProperty & SpreadProperty

兩個 AST 節點 RestPropertySpreadProperty 已移除,改為重複使用 RestElementSpreadElement #384

 return {
SpreadElement(path) {
- ...
- },
- SpreadProperty(path) {
- ...
+ if (path.parentPath.isObjectExpression()) {
+ ...
+ } else if (path.parentPath.isArrayExpression()) {
+ ...
+ }
},
RestElement(path) {
- ...
- },
- RestProperty(path) {
- ...
+ if (path.parentPath.isObjectPattern()) {
+ ...
+ } else if (path.parentPath.isArrayPattern()) {
+ ...
+ }
}
};

請參閱我們的 Babel 升級 PRBabylon AST 規格,以取得更多資訊。