babel是怎样工作的

更新日期: 2020-12-18阅读: 1.6k标签: babel

babel 本质上是个编译器,所以它所做的基本上就是编译器要做的事,为了避免对编译器的某些东西讲的太细,我们重点只要知道 babel 的工作流程就行了。


转换成AST

第一步可以说是是编译器的基本功能,通过解析器将原始代码转换成抽象语法树(AST),顾名思义就是描述语法的数据结构,一般在这一步编译器都会做两件事:语法分析与语义分析。语法分析是去定义原始代码中的内容是否应该被认为一个单位,然后是语义分析,判断这些单位组合而成的是否为语法,例如用于 for 循环等,在这一步中实际上插件几乎什么也做不了,因为 babel 并不支持改变解析的流程

但 babel 有几个内建的解析插件,这部份可以由plugin去开关,不过这一般也会通过官方的plugin去开关这些功能,主要是确保不会直接使用到babel内部的选项,这就是babel官方插件的名字中带有syntax的插件在做的事。

这里要介绍一个工具:AST Explorer,它可以让你可以看到各种语言的 AST 语法树,也可以在这上面测试 babel 插件,这对要写 babel 插件的人来说非常方便,后面会用这个工具来帮我们写一个 babel 插件。先来一个例子:

function answer() {
  return 'The answer to life, the universe and everything'
}

转成 AST 后大概就是这样,这里用 json 表示并省略了位置等信息:

{
  "type": "File",
  "program": {
    "type": "Program",
    "body": [
      {
        "type": "FunctionDeclaration",
        "id": {
          "type": "Identifier",
          "name": "answer"
        },
        "body": {
          "type": "BlockStatement",
          "body": [
            {
              "type": "ReturnStatement",
              "argument": {
                "type": "StringLiteral",
                "value": "The answer to life, the universe and everything"
              }
            }
          ]
        }
      }
    ]
  }
}
补充:ASTExplorer 支持很多程序语言,js、css、go、python 等,有兴趣可以玩玩。


遍历 AST

babel 会按顺序访问每个 AST 上的节点,并调用插件对应的函数,这一步才是插件要做的,在遍历时 babel 会为每个节点建立一个名为 Path 的对象,这个对象会包含这个节点的信息,也可以让你访问它的父节点或子节点,同时在这个对象上也会有各种方法让你来修改节点的内容与结构,从而替换掉一个结点:

export default function (babel) {
  const { types: t } = babel;
  
  return {
    visitor: {
      StringLiteral(path) { // 如果遇到一个字符串常数
        // 常数的内容是指定的字符串
        if (path.node.value === 'The answer to life, the universe and everything') {
          path.replaceWith(t.numericLiteral(42)) // 换成数字的 42
        }
      }
    }
  };
}

上面的代码就可以用 AST Explorer 试试了,点击 AST Explorer 上面的 Transform 的菜单,选择 babelv7 后,下面就会多一个编辑器让你输入,上面的代码就可以直接使用了


产生代码

最后 babel 会把修改过的 AST 再转回代码。

function answer() {
  return 42;
}

剩下的工作就是写入文件,或者再进一步处理。其实转换回代码后 babel 的工作就结束了。


    链接: https://fly63.com/article/detial/9973

    Babel中的stage-0,stage-1,stage-2以及stage-3的作用(转)

    大家知道,将ES6代码编译为ES5时,我们常用到Babel这个编译工具。大家参考一些网上的文章或者官方文档,里面常会建议大家在.babelrc中输入如下代码

    深入理解Babel原理及其使用,babel把ES6转成ES5的原理是什么?

    文的babel使用场景局限于babel配合webpack来转译输出es5的js代码,babel的命令行、以代码形式调用或node环境下这些统统都不会涉及。Babel使用的难点主要在于理解polyfill、runtime和core-js。

    ES6之Babel的各种坑总结【转载】

    自从 Babel 由版本5升级到版本6后,在安装和使用方式上与之前大相径庭,于是写了这篇入坑须知,以免被新版本所坑。坑一本地安装和全局安装 、坑二编译插件、坑三babel-polyfill插件

    babel-preset-env:一个帮你配置babel的preset

    babel-preset-env 一个帮你配置babel的preset,根据配置的目标环境自动采用需要的babel插件。babel-preset-env 功能类似 babel-preset-latest,优点是它会根据目标环境选择不支持的新特性来转译

    babel-polyfill使用与性能优化

    本文主要内容包括:什么是babel-polyfill,如何使用,如何通过按需加载进行性能优化。babel只负责语法转换,比如将ES6的语法转换成ES5。但如果有些对象、方法,浏览器本身不支持,此时需要引入babel-polyfill来模拟实现这些对象、方法。

    babel的初步了解

    由于现在前端出现了很多非es5的语法,如jsx,.vue,ts等等的格式和写法。babel其实是一个解释器,它主要讲进行中的代码分为三个阶段执行:解释,转换,生成。

    深入类和继承内部原理+Babel和 TypeScript 之间转换

    在 JavaScript 中,没有基本类型,创建的所有东西都是对象。例如,创建一个新字符串,与其他语言不同,在 JavaScript 中,字符串或数字的声明会自动创建一个封装值的对象,并提供不同的方法,甚至可以在基本类型上执行这些方法。

    使用 Webpack 与 Babel 配置 ES6 开发环境

    在项目根目录下新建一个配置文件—— webpack.config.js 文件:执行编译打包命令,完成后打开 bundle.js 文件发现 isNull 和 unique 两个函数没有被编译,和 webpack 官方说法一致:webpack 默认支持 ES6 模块语法,要编译 ES6 代码依然需要 babel 编译器。

    Babel_如何写一个Babel插件

    Babel对代码进行转换,会将JS代码转换为AST抽象语法树(解析),对树进行静态分析(转换),然后再将语法树转换为JS代码(生成)。每一层树被称为节点。每一层节点都会有type属性,用来描述节点的类型。其他属性用来进一步描述节点的类型。

    初学 Babel 工作原理

    Babel 对于前端开发者来说应该是很熟悉了,日常开发中基本上是离不开它的。我们已经能够熟练地使用 es2015+ 的语法。但是对于浏览器来说,可能和它们还不够熟悉,我们得让浏览器理解它们,这就需要 Babel

    点击更多...

    内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!