babel笔记(持续更新)

138 阅读2分钟

AST 节点

Literal 字面量

  • StringLiteral
  • NumericLiteral
  • BooleanLiteral
  • RegExpLiteral
  • TemplateLiteral
  • BooleanLiteral
  • BigintLiteral
  • NullLiteral

Identifier 标识符

Statement 语句(独立执行的)

Declaration 声明语句

  • VariableDeclaration
  • FunctionDeclaration
  • ClassDeclaration
  • ImportDeclaration
  • ExportDefaultDeclaration
  • ExportNameDeclaration
  • ExportAllDeclaration

Expression(是执行完以后有返回值)

  • ArrayExpression
  • AssignmentExpression
  • BinaryExpression
  • UnaryExpression
  • FunctionExpression
  • ArrowFunctionExpression
  • ClassExpression
  • Identifier
  • thisExpression
  • Super
  • BindExpression

parse (通过 parser 把源码转成抽象语法树 AST )

@babel/parser (源码 -> AST)

  • parse(将提供的代码作为一个完整的ECMAScript项目进行解析)

    • babelParser.parse(code, [options])
  • parseExpression(解析单个表达式--性能)

    • babelParser.parseExpression(code, [options])
  • Options(常用参数并非全部参数)

    • allowXxx: 指定一些语法是否允许,比如函数外的 await、没声明的 export等
    • plugins: 启用的插件的数组
    • sourceType: 指定是否支持解析模块语法
    • strictMode 是否是严格模式
    • startLine 从源码哪一行开始 parse
    • errorRecovery 出错时是否记录错误并继续往下 parse
    • tokens parse 的时候是否保留 token 信息
    • ranges 是否在 ast 节点中添加 ranges 属性

transform(遍历 AST,调用各种 transform 插件对 AST 进行增删改)

@babel/traverse

  • traverse
    • function traverse(parent, opts)
  • opts 对 AST 操作的函数
    • enter(path,state) {} 调用是在遍历当前节点的子节点前调用
    • exit(path,state) {} 调用是遍历完当前节点的子节点后调用 -path
      • path.node 指向当前 AST 节点
      • path.get、path.set 获取和设置当前节点属性的 path
      • path.parent 指向父级 AST 节点
      • path.getSibling、path.getNextSibling、path.getPrevSibling 获取兄弟节点
      • path.find 从当前节点向上查找节点
      • path.scope 获取当前节点的作用域信息
      • path.isXxx 判断当前节点是不是 xx 类型
      • path.assertXxx 判断当前节点是不是 xx 类型,不是则抛出异常
      • path.insertBefore、path.insertAfter 插入节点
      • path.replaceWith、path.replaceWithMultiple、replaceWithSourceString 替换节点
      • path.remove 删除节点
      • path.skip 跳过当前节点的子节点的遍历
      • path.stop 结束后续遍历
    • state

@babel/types(遍历 AST 的过程中需要创建一些 AST 和判断 AST 的类型)

  • t.ifStatement(test, consequent, alternate); 创建
  • t.isIfStatement(node, opts);判断

@babel/template(包来批量创建 AST 节点比较多)

  • template(code, [opts])(args);

generate(把转换后的 AST 打印成目标代码,并生成 sourcemap)

@babel/generator(AST 转换完之后就要打印成目标代码字符串)

  • function (ast: Object, opts: Object, code: string): {code, map}
    • ast:要翻译的 ast
    • options:指定打印的一些细节,比如通过 comments 指定是否包含注释,通过 minified 指定是否包含空白字符
    • code:当多个文件合并打印的时候需要用到

@babel/code-frame(当有错误信息要打印的时候,需要打印错误位置的代码)

  • codeFrameColumns(rawLines, location, {options});
  • options:高亮

@babel/core(前面的包是完成某一部分的功能的,而 @babel/core 包则是基于它们完成整个编译流程,从源码到目标代码,生成 sourcemap)

  • transformSync(code, options); // => { code, map, ast }

  • transformFileSync(filename, options); // => { code, map, ast }

  • transformFromAstSync( parsedAst, sourceCode, options ); // => { code, map, ast }

  • transformAsync("code();", options).then(result => {})

  • transformFileAsync("filename.js", options).then(result => {})

  • transformFromAstAsync(parsedAst, sourceCode, options).then(result => {})