美文网首页
深入webpack之babel 与 AST

深入webpack之babel 与 AST

作者: 左冬的博客 | 来源:发表于2021-08-05 10:53 被阅读0次

babel的原理

  • parse:把代码code变成AST
  • traverse:遍历AST进行修改
  • generate:把AST变成代码code2
    即 code -> ast -> ast2 -> code2

示例:手动把let变成var

import { parse } from "@babel/parser" // 把代码`code`变成`AST`
import traverse from "@babel/traverse" // 遍历AST
import generate from "@babel/generator" // 把`AST`变成代码`code2`

const code = `let a = 'let'; let b = 2`
const ast = parse(code, { sourceType: 'module' })
traverse(ast, {
  enter: item => {
    if(item.node.type === 'VariableDeclaration'){
      if(item.node.kind === 'let'){
        item.node.kind = 'var'
      }
    }
  }
})
const result = generate(ast, {}, code)
console.log(result.code)

在Chrome运行TS代码:node -r ts-node/register --inspect-brk xxx.ts

先打印看看ast是什么:

AST对象
从ast对象的属性中,可以看到这个program就是上面code这段代码的程序,程序的body里有两个节点:
// const code = `let a = 'let'; let b = 2`
let a = 'let' // 节点1
let b = 2 // 节点2

再看一下这些节点都包含哪些属性,重点关注这三个属性

...
// 声明的节点信息
declarations: [Node]
// 变量声明的关键字是let
kind: "let"
// 类型,说明是一个变量声明
type: "VariableDeclaration"
...

// declarations是一个节点数组,因为可以同时声明多个节点
// let a = 'let'
// name为a的标识符,对应初始值value是'let',类型是字符串
declarations: [
    0: Node
        {
            id: {
                ...,
                name: "a",
                type: "Identifier"
            },
            init: {
                ...,
                value: "let",
                type: "StringLiteral"
            }
    },
    length: 1
]

所以说AST就是用来将源代码字符串,表示成一个树形结构

// traverse用来遍历AST,可以对AST进行修改
traverse(ast, {
// 每进入一个节点,就执行item=>{}函数
  enter: item => {
    ...
  }
})

这样看来,将let变成var就水到渠成了

traverse(ast, {
  enter: item => {
    if(item.node.type === 'VariableDeclaration'){ // 如果是变量声明
      if(item.node.kind === 'let'){ // 如果是let声明
        item.node.kind = 'var' // 将let改成var
      }
    }
  }
})

再使用generate函数将新的AST翻译成code

const result = generate(ast, {}, code) // 传入修改后的ast,还有原始code
console.log(result.code) // 得到新的code

运行后就得到了

var a = 'let';
var b = 2;

为什么要用AST

  • 你很难用正则表达式去替换,正则很容易把let a = 'let'变成var a = 'var'
  • 你需要识别每个单词的意思,才能做到只修改用于变量声明的let
  • 而AST能明确告诉你每个let的意思

下篇《如何将代码转为ES5》

相关文章

  • 深入webpack之babel 与 AST

    babel的原理 parse:把代码code变成AST traverse:遍历AST进行修改 generate:把...

  • AST、Babel、依赖

    babel 与 AST 先从Babel 说起 babel 的原理1、parse:把代码 code 变成 AST2、...

  • 【Webpack】AST、babel、依赖

    babel babel的原理 1、parse:把代码变成AST2、traverse:遍历AST进行修改;3、gen...

  • babel插件入门-AST

    目录 Babel简介 Babel运行原理 AST解析 AST转换 写一个Babel插件 Babel简介 Babel...

  • 一个bebel插件

    Babel它的原理,简单点说: Babel解析成AST,然后插件更改AST,最后由Babel输出代码

  • babel 与 AST

    babel原理 parse把代码code 变成 ast traverse 遍历ast 进行修改 generate ...

  • AST与babel

    AST 什么是ast ast又称抽象语法树,以树形结构描述代码,一般是json对象。与ast相关的操作通常有三...

  • webpack使用Babel处理ES6语法

    安装配置 babel-loader与@babel/core babel-loader : webpack与Babe...

  • vue3原理

    AST AST:抽象语法树,Abstract Syntax Tree。TypeScript、babel、webpa...

  • AST、Babel、依赖

    Babel babel 的原理 parse: 把代码 code 变成 ASTtraverse: 遍历 AST 进行...

网友评论

      本文标题:深入webpack之babel 与 AST

      本文链接:https://www.haomeiwen.com/subject/uvfuvltx.html