Babel 插件
作者:知否
來源:SegmentFault 思否社區(qū)
Babel 是一個編譯器,和其他編譯器一樣,編譯過程分為三個階段,分別是解析(parsing)、轉(zhuǎn)換(transforming)和生成(generate)。其中分析和生成階段由 Babel 核心完成,而轉(zhuǎn)換階段,則由Babel插件完成。所以如果我們要實現(xiàn)代碼的轉(zhuǎn)換,需要為 Babel 添加插件。Babel 也提供了很多的接口來供我們編寫自身的插件來轉(zhuǎn)換我們的實際代碼。
插件的介紹
下面是一個典型的 Babel 插件結(jié)構(gòu):
export default function({ types: babelTypes }) {
return {
visitor: {
Identifier(path, state) {},
ASTNodeTypeHere(path, state) {}
}
};
};
其中我們需要關注的內(nèi)容如下:
babelType:類似 lodash 那樣的工具集,主要用來操作 AST 節(jié)點,比如創(chuàng)建、校驗、轉(zhuǎn)變等。例如判斷某個節(jié)點是不是標識符。
path:AST 中有很多節(jié)點,每個節(jié)點可能有不同的屬性,并且節(jié)點之間可能存在關聯(lián)。path 是個對象,它代表了兩個節(jié)點之間的關聯(lián)。我們可以在 path 上訪問到節(jié)點的屬性,也可以通過 path 來訪問到關聯(lián)的節(jié)點。
state:代表了插件的狀態(tài),我們可以通過 state 來訪問插件的配置項。
visitor:Babel 采取遞歸的方式訪問 AST 的每個節(jié)點,之所以叫做 visitor,只是因為有個類似的設計模式叫做訪問者模式,不用在意背后的細節(jié)。
Identifier、ASTNodeTypeHere:AST 的每個節(jié)點,都有對應的節(jié)點類型,比如標識符、函數(shù)聲明等,可以在 visitor 上聲明同名的屬性,當 Babel 遍歷到相應類型的節(jié)點,屬性對應的方法就會被調(diào)用,傳入的參數(shù)就是 path、state。
插件的使用
npm install --save-dev @babel/cli
module.exports = function({ types: babelTypes }) {
return {
name: "simple-plugin-replace",
visitor: {
Identifier(path, state) {
if (path.node.name === 'a') {
path.node.name = 'xkd';
}
}
}
};
};
var a = 10;
function func(){
var a = 20;
console.log(a);
}
npx babel --plugins ./plugin.js index.js
"use strict";
var xkd = 10;
function func() {
var xkd = 20;
console.log(xkd);
}
插件配置
{
"plugins": [ ["./plugin", {
"a": "one",
"b": "two"
}] ]
}
module.exports = function({ types: babelTypes }) {
return {
name: "simple-plugin-replace",
visitor: {
Identifier(path, state) {
let name = path.node.name;
if (state.opts[name]) {
path.node.name = state.opts[name];
}
}
}
};
};
let a = 10;
let b = 20;
let one = 10;
let two = 20;
轉(zhuǎn)譯插件
ES3
member-expression-literals
property-literals
reserved-words
ES5
property-mutators
ES2015
arrow-functions
block-scoped-functions
block-scoping
classes
computed-properties
destructuring
duplicate-keys
for-of
function-name
instanceof
literals
new-target
object-super`parameters
shorthand-properties
spread
sticky-regex
template-literals
typeof-symbol
unicode-escapes
unicode-regex
ES2016
exponentiation-operator
ES2017
async-to-generator
ES2018
async-generator-functions
dotall-regex
named-capturing-groups-regex
object-rest-spread
optional-catch-binding
unicode-property-regex
Modules
modules-amd
modules-commonjs
modules-systemjs
modules-umd
Experimental
class-properties
decorators
do-expressions
export-default-from
export-namespace-from
function-bind
function-sent
logical-assignment-operators
nullish-coalescing-operator
numeric-separator
optional-chaining
partial-application
pipeline-operator
private-methods
throw-expressions
private-property-in-object
語法插件
{
"parserOpts": {
"plugins": ["jsx", "flow"]
}
}

