@babel/types
@babel/types 相关简介 以及用法 types 主要用来创建、判断类型等 搭配
@babel/generator
来生成代码。
创建相关
下面是基础代码使用
@babel/generator
生成代码
js
// index.js
import * as types from '@babel/types'
import gen from '@babel/generator'
const log = (node) => {
console.log(node,'node')
console.log(gen(node).code)
}
- stringLiteral 创建字符传数据 返回值 ({ type: 'StringLiteral', value: 'string' })
- numericLiteral 创建数值数据 ({ type: 'NumericLiteral', value: 100000 })
- booleanLiteral 创建布尔数据({ type: 'BooleanLiteral', value: true })
- regExpLiteral 创建正则表达式 ({ type: 'RegExpLiteral', pattern: '\.jsx?$', flags: 'g' })
code:
js
// 创建基础数据
const createString = types.stringLiteral('id');
const createNumber = types.numericLiteral(10e4);
const createBoolean = types.booleanLiteral(true);
const createRegExp = types.regExpLiteral('\\.jsx?$', 'g');
const createNull = types.nullLiteral();
log(createString);
log(createNumber);
log(createBoolean);
log(createRegExp);
log(createNull);
输出:
bash
{ type: 'StringLiteral', value: 'id' } node
"id"
{ type: 'NumericLiteral', value: 100000 } node
100000
{ type: 'BooleanLiteral', value: true } node
true
{ type: 'RegExpLiteral', pattern: '\\.jsx?$', flags: 'g' } node
/\.jsx?$/g
{ type: 'NullLiteral' } node
null
数组、对象
创建数组对象
- arrayExpression([]) 数组里面可以是
types.stringLiteral
.... - objectExpression([]) 数组俩面使用
types.objectProperty()
创建每组对象 - objectMethod() 创建对象方法
- types.objectProperty(key, value, computed, shorthand, decorators)
- key 可以是
types.stringLiteral('id')
/types.identifier('id')
等 - value 可以是
types.stringLiteral('id')
/types.identifier('id')
等 - computed: boolean 默认false。 true下会生成{[id]: 123} key变成动态的了。
- shorthand: boolean 默认false。true会简写对象 {id}样
- key 可以是
code:
js
// 创建数组
const createArray = types.arrayExpression([
createString, // 上面的变量
createNumber, // 上面的变量
]);
log(createArray);
// 创建对象
// t.objectProperty(key, value, computed, shorthand, decorators);
/**
* key: if computed then Expression else Identifier | Literal (required)
value: Expression | PatternLike (required)
computed: boolean (default: false)
shorthand: boolean (default: false)
decorators: Array<Decorator> (default: null)
*/
const createObject = types.objectExpression([
types.objectProperty(createString, createNumber, true, false),
types.objectProperty(types.identifier('id'), types.identifier('id'), false, true),
]);
// types.stringLiteral('id') / types.identifier('id') 区别是:"id" / id
log(createObject);
输出:
bash
{
type: 'ArrayExpression',
elements: [
{ type: 'StringLiteral', value: 'id' },
{ type: 'NumericLiteral', value: 100000 }
]
} node
["id", 100000]
{
type: 'ObjectExpression',
properties: [
{
type: 'ObjectProperty',
key: [Object],
value: [Object],
computed: true,
shorthand: false,
decorators: null
},
{
type: 'ObjectProperty',
key: [Object],
value: [Object],
computed: false,
shorthand: true,
decorators: null
}
]
} node
{
[id]: 100000,
id
}
创建函数
创建具名函数和箭头函数
- functionDeclaration() 具名函数:
function test() {}
- arrowFunctionExpression() 箭头表达式函数:
() => {}
- blockStatement() 块语句:
{}
- expressionStatement() 表达式语句
- callExpression() 调用表达式/函数 第一个参数函数名 第二个参数函数入参:
console.log(a,b,c)
- returnStatement() return 语句
- binaryExpression() 二元表达式 参数1 操作符, 参数2 左侧 参数3 右侧 :
a + b
用法如下
js
// 创建具名函数
const createFunc1 = types.functionDeclaration(
types.identifier('test'), // 函数名
[types.identifier('arg1'), types.identifier('arg2')], // 函数参数
types.blockStatement([ // 块语句
types.expressionStatement(
types.callExpression(
types.identifier('console.log'), // 被调用的函数名
[types.identifier('arg1'), types.identifier('arg2')] // 入参数
)
),
types.returnStatement( // return 语句
types.binaryExpression('+', types.identifier('arg1'), types.identifier('arg2')) // 二元表达式
),
]),
false, // 是否async
)
log(createFunc1)
// 创建箭头函数表达式
const createFunc2 = types.arrowFunctionExpression(
[types.identifier('arg1'), types.identifier('arg2')], // 参数
types.callExpression(
types.identifier('console.log'), // 被调用的函数名
[types.identifier('arg1'), types.identifier('arg2')] // 入参数
),
true, // 是否async
)
log(createFunc2)
输出:
bash
function test(arg1, arg2) {
console.log(arg1, arg2);
}
# 此处可以思考:为什么没有箭头函数声明,以及Declaration和Expression的区别
async (arg1, arg2) => console.log(arg1, arg2)
变量声明(函数表达式、箭头函数表达式使用)
变量声明 以及带你理解表达式(Expression)声明(Declaration)区别
- variableDeclaration() 变量声明参数1是
count/let/var
, 参数2是variableDeclarator
集合或者单个 - variableDeclarator() 变量声明者参数1是变量名
types.identifier('a1')
, 参数2是默认值a1 = 123 || a1;
变量声明用法如下:
js
const createA1 = types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('a1'),
),
]);
const createA2 = types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('a2'),
types.numericLiteral(123), // 初始值 const a = 1;
),
]);
log(createA1)
log(createA2)
输出:
bash
const a1;
const a2 = 123;
函数表达式、箭头函数表达式结合变量声明如下:
- functionExpression()
const a = function(){}
- arrowFunctionExpression()
const a = () => {}
js
// 箭头函数表达式
const createFunc2 = types.arrowFunctionExpression(
[types.identifier('arg1'), types.identifier('arg2')], // 参数
types.callExpression(
types.identifier('console.log'), // 被调用的函数名
[types.identifier('arg1'), types.identifier('arg2')] // 入参数
),
true, // 是否async
)
// 函数表达式
const createFunc3 = types.functionExpression(
types.identifier('test3'),
[types.identifier('arg1'), types.identifier('arg2')],
types.blockStatement([
types.expressionStatement(
types.callExpression(
types.identifier('console.log'), // 被调用的函数名
[types.identifier('arg1'), types.identifier('arg2')] // 入参数
)
)
]),
false, // generator
true, // async
)
const createA3 = types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('a1'),
createFunc2, // 箭头函数表达式
),
]);
const createA4 = types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('a2'),
createFunc3, // 普通函数表达式
),
]);
log(createA3)
log(createA4)
输出:
bash
const a1 = async (arg1, arg2) => console.log(arg1, arg2);
const a2 = async function test3(arg1, arg2) {
console.log(arg1, arg2);
};
结论:函数表达式是可以赋值给变量使用的
await 表达式(awaitExpression)、 成员表达式(memberExpression)
介绍
awaitExpression
和memberExpression
表达式的具体用法实践
- awaitExpression
await a()
- memberExpression
a.b.c
awaitExpression 使用
js
// awaitExpression
const createFunc4 = types.functionDeclaration(
types.identifier('test2'),
[types.identifier('arg1'), types.identifier('arg2')], // 函数参数
types.blockStatement([
types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('a3'),
types.awaitExpression(
types.binaryExpression('+', types.numericLiteral(2), types.numericLiteral(3))
),
),
])
]),
false, // generator
true, // async
)
log(createFunc4)
输出:
bash
async function test2(arg1, arg2) {
const a3 = await (2 + 3);
}
memberExpression
用法(补充objectMethod
用法)
js
const createObject2 = types.objectExpression([
types.objectProperty(
types.identifier('a'),
types.stringLiteral('123'),
),
types.objectMethod(
'method',
types.identifier('fn'),
[types.identifier('args1')],
types.blockStatement([
types.expressionStatement(
types.callExpression(
types.identifier('console.log'), // 被调用的函数名
[types.identifier('arg1'), types.identifier('arg2')] // 入参数
)
)
])
)
])
const b1 = types.memberExpression(createObject2,types.identifier('a'));
log(b1)
输出:
bash
{
a: "123",
fn(args1) {
console.log(arg1, arg2);
}
}.a
扩展运算符(spreadElement)
介绍使用扩展运算符
js
const createArray = types.arrayExpression([types.stringLiteral('id'), types.stringLiteral('id')]);
const b2 = types.arrayExpression([
types.spreadElement(createArray)
]);
log(b2);
输出:
bash
[...["id", "id"]]
try catch
使用try catch包裹
- tryStatement
- catchClause
js
const createTryCatch = types.tryStatement(types.blockStatement([
types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('a1'),
),
])
]), types.catchClause(
types.identifier('error'),
types.blockStatement([
types.expressionStatement(
types.callExpression(
types.identifier('console.log'), // 被调用的函数名
[types.identifier('error'),types.stringLiteral('error')] // 入参数
)
)
])
))
log(createTryCatch)
输出:
js
try {
const a1;
} catch (error) {
console.log(error, "error");
}
其他常用
ifStatement
(if)if () {}forStatement
(for)for (;😉{}forInStatement
(for in)or (a in b) {}forOfStatement
(for of)for (a of b) {}importDeclaration
(import声明)import 'a'importDefaultSpecifier
(import default说明符)import a from 'a'ImportSpecifier
(import说明符)import {a} from 'a'newExpression
(new表达式)new A()classDeclaration
(class声明)class A {}classBody
(class body)class A {}(类的内部)