Skip to content
On this page

@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}样

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)

介绍awaitExpressionmemberExpression 表达式的具体用法实践

  • 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 {}(类的内部)

Released under the MIT License.