Babel 插件
作者:知否
来源:SegmentFault 思否社区
Babel 是一个编译器,和其他编译器一样,编译过程分为三个阶段,分别是解析(parsing)、转换(transforming)和生成(generate)。其中分析和生成阶段由 Babel 核心完成,而转换阶段,则由Babel插件完成。所以如果我们要实现代码的转换,需要为 Babel 添加插件。Babel 也提供了很多的接口来供我们编写自身的插件来转换我们的实际代码。
插件的介绍
下面是一个典型的 Babel 插件结构:
export default function({ types: babelTypes }) {
return {
visitor: {
Identifier(path, state) {},
ASTNodeTypeHere(path, state) {}
}
};
};
其中我们需要关注的内容如下:
babelType:类似 lodash 那样的工具集,主要用来操作 AST 节点,比如创建、校验、转变等。例如判断某个节点是不是标识符。
path:AST 中有很多节点,每个节点可能有不同的属性,并且节点之间可能存在关联。path 是个对象,它代表了两个节点之间的关联。我们可以在 path 上访问到节点的属性,也可以通过 path 来访问到关联的节点。
state:代表了插件的状态,我们可以通过 state 来访问插件的配置项。
visitor:Babel 采取递归的方式访问 AST 的每个节点,之所以叫做 visitor,只是因为有个类似的设计模式叫做访问者模式,不用在意背后的细节。
Identifier、ASTNodeTypeHere:AST 的每个节点,都有对应的节点类型,比如标识符、函数声明等,可以在 visitor 上声明同名的属性,当 Babel 遍历到相应类型的节点,属性对应的方法就会被调用,传入的参数就是 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;
转译插件
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"]
}
}