文档章节

Babel 插件手册 笔记

一个人的中台
 一个人的中台
发布于 02/22 12:14
字数 1773
阅读 76
收藏 0

来源:https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md

Babel 的使用就是使用一些预设配置。预设就是一组插件,比如env,  stage-3   flow  react  typescript预设。
Babel的核心就是插件,插件就是基于核心函数,对AST树的一些操作
Babel 核心的核心就是一组函数
     【重要函数】 parser  traverse  generator  core.parser  core.transorm
     【辅助函数】 code-frame  helpers  template  types  
 
Babel 插件手册是官网编写的插件指南!涉及基本概念,API,转换操作,构建节点,最佳实践等部分

一、基本概念

AST抽象语法树

所有类型节点都有Node 接口以及其它参数,比如代码的起始位置,参数,左右节点等等:

interface Node {
  type: string;
}

Babel处理步骤

Babel 的三个主要处理步骤分别是: 解析(parse)转换(transform)生成(generate)。.

遍历AST之访问者模式:

       通过访问者模式,访问每一个节点!     深度递归遍历整个树。 

1、访问者名字

最普通是用Node 的 type 名为访问者的名字, 它是一个函数,但有几种高级用法 ,见下面示例

const MyVisitor = {
  //  1、所有节点类型进入  参见:https://www.babeljs.cn/docs/babel-traverse#usage
  enter(path){}
  //  2、某类型的进入或退出
  Identifier: {
    enter() {
      console.log("Entered!");
    },
    exit() {
      console.log("Exited!");
    }
  }
  //  3、通过某个类型名称
  MemberExpression(){     }
  //  4、通过helps中定义 的 别名
  Function(path) {}
  //  5、同时匹配几种类型
  "ExportNamedDeclaration|Flow"(path) {}
}

babel-types中已定义一组别名,比如Function 可以代表多种Node类型, FunctionDeclaration, FunctionExpression, ArrowFunctionExpression, ObjectMethod and ClassMethod 。参见下面源码

 

2、访问者的参数--path:

第一感觉,这个参数应该是Node,但通过前面代码可以发现它叫:path。

其实参数是Path对象,它是表示两个节点之间连接的对象。 在巨大的AST树中,用来表示节点的位置的对象,Path对象的node才是节点本身,parent是父节点对象。  还有其它很多相关属性,   恩,想想也满合理的设计,为插件编写者省了不少力!

{
  "parent": {...},
  "node": {...},   
  "hub": {...},
  "contexts": [],
  "data": {},
  "shouldSkip": false,
  "shouldStop": false,
  "removed": false,
  "state": null,
  "opts": null,
  "skipKeys": null,
  "parentPath": null,
  "context": null,
  "container": null,
  "listKey": null,
  "inList": false,
  "parentKey": null,
  "key": null,
  "scope": null,
  "type": null,
  "typeAnnotation": null
}

3、执行访问者:

traverse(someAST  , MyVisitor )

每一个path对象也可以traverse.   path.traverse(  SomeVisitor ,  contextObj) 。此时就不传入AST了,因为path已然包含AST信息, 第二个参数contextObj是表示传入SomeVisitor访问都的上下文,可以通过this.xxxValue来访问。

4、(访问者间的)States

官方的例子看的人难受, 我以为它是想说明这样一个问题:

     所有的匹配到的访问者函数会被调用,在函数中,不应该使用全局变量(也访问者函数之外的变量),来维护某一个States。

如果我在某一个访问函数中,计算出一个值,想把这个值传递给下级的AST树,让下级节点处理某一个操作时,  应该在当前位置执行一个新的traverse,  此即相当于嵌套递归。  前面的计算值可以通过对象contextObj 传递给下级AST树     path.traverse(  SomeVisitor ,  contextObj)

5、Scopes 和 Binding

说实话,真看不懂呀!Scope就是一个层层嵌套的作用域,也叫Block,它包含Path(比Path还大一级的东西 )  Binding则用于从Scope中去访问变量!

二  重要的API

这部分直接看Babel官方文档更好理解,https://www.babeljs.cn/docs/babel-parser

1、babylon(  相当于Babel)

babylon引入Parse方法,解析code字符串。 但在2018年,babylon就废弃了,变成Babel.parse了。  从这个角度说明,这份中文的Babel插件文档已经2年未更新了,内容过时了。 去官网文档英文版查找追踪过来,内容和中文版一致。

2、traverse

Babel Traverse(遍历)模块维护了整棵树的状态,并且负责替换、移除和添加节点。

3、Babel Types 

Types包含一组函数,每个节点类型的定义节点构造器节点验证器,Converters(变换器)!  

其中Converters(变换器)的内容未编写

由于以下内容,简短且重要的概念,转引过来!

Babel Types模块是一个用于 AST 节点的工具库, 它包含了构造、验证以及变换 AST 节点的方法。 该工具库包含考虑周到的工具方法,对编写处理AST逻辑非常有用。 它还包含Definitions ,拥有每一个单一类型节点的定义,包括节点包含哪些属性,什么是合法值,如何构建节点、遍历节点,以及节点的别名等信息。

单一节点类型的定义Definitions 形式如下:

defineType("BinaryExpression", {
  builder: ["operator", "left", "right"],
  fields: {
    operator: {
      validate: assertValueType("string")
    },
    left: {
      validate: assertNodeType("Expression")
    },
    right: {
      validate: assertNodeType("Expression")
    }
  },
  visitor: ["left", "right"],
  aliases: ["Binary", "Expression"]
});

你会注意到上面的 BinaryExpression 定义有一个 builder 字段。.

builder: ["operator", "left", "right"]

这是由于每一个节点类型都有构造器方法builder,按类似下面的方式使用:

t.binaryExpression("*", t.identifier("a"), t.identifier("b"));

可以创建如下所示的 AST:

{
  type: "BinaryExpression",
  operator: "*",
  left: {
    type: "Identifier",
    name: "a"
  },
  right: {
    type: "Identifier",
    name: "b"
  }
}

当打印出来之后是这样的:

a * b

构造器还会验证自身创建的节点,并在错误使用的情形下会抛出描述性错误,这就引出了Validators(验证器)

BinaryExpression 的定义还包含了节点的字段 fields 信息,以及如何验证这些字段。

fields: {
  operator: {
    validate: assertValueType("string")
  },
  left: {
    validate: assertNodeType("Expression")
  },
  right: {
    validate: assertNodeType("Expression")
  }
}

4、Babel Generator模块

Babel 的代码生成器,它读取AST并将其转换为代码和源码映射(sourcemaps)。

generate(ast, {
  retainLines: false,
  compact: "auto",
  concise: false,
  quotes: "double",
  // ...
}, code);

这里想不明白的是,为什么第三个参数是code,原代码的原文??

5、babel-template

是另一个虽然很小但却非常有用的模块。 它能让你编写字符串形式且带有占位符的代码来代替手动编码, 尤其是生成的大规模 AST的时候。 在计算机科学中,这种能力被称为准引用(quasiquotes)。

三  编写Babel插件

由于插件是被Babel调用的工具链上的一个步骤,所以它只关注Ast 的编辑动作即可, AST的解析与代码生成它都不必关心!所以它接收一个Babel对象作为入参,返回一个Vistor对象!

export default function(babel) {
  return {
    visitor: {
      Identifier(path, state) {}
    }
  };
};

四  转换操作

既然了解了基本概念,API和插件的写法, 那么知道我们在插件里,能怎么操作AST,怎么辗转腾挪就是重点,这些能力就决定了插件的能力!现在有很多UI框架可以适配多端平台,比如Taro,  uni之类的框架,大概都是基于这种技术实现的。针对一个框架编写的代码如何生成多端适配的代码呢,那就看一下Babel的变换能力吧!

 

 

 

 

 

© 著作权归作者所有

一个人的中台
粉丝 18
博文 79
码字总数 49913
作品 0
深圳
程序员
私信 提问
加载中

评论(0)

babel-plugin-macros:babel的另一种配置方式

翻译引用了文章 Babel macros 前言 对于现代的前端项目而言,webpack和babel是两个无法回避的工具。 相比于webpack的热度,以及webpack配置工程师等热门岗位,babel要默默无闻很多,但这并不...

supot
01/22
0
0
你会 babel 插件么?我也不会

在一个月黑风高的晚上,小黄问我 你知道么? 我: 我靠, 我肯定知道啊,你这是在侮辱谁? 小黄: 那你知道 是怎么工作的么? 我: 当然了,第一步是进行词法、语法解析,解析成 AST,第二步就是...

小烜同学
2019/05/16
0
0
🇨🇳国庆还有人看文吗?深入浅出 Babel 上篇:架构和原理 + 实战

国庆放假了,我还在利用碎片时间在写文章,不知道长假还有没有人看,试试水吧! 这个文章系列将带大家深入浅出 , 这个系列将分为上下两篇:上篇主要介绍 Babel 的架构和原理,顺便实践一下插...

_sx_
2019/10/02
0
0
通过开发 Babel 插件来理解什么是抽象语法树(AST)

前言 说到 babel 你肯定会先想到 babel 可以将还未被浏览器实现的 ES6 规范转换成能够运行 ES5 规范,或者可以将 JSX 转换为浏览器能识别的 HTML 结构,那么 babel 是如何进行这个转换的步骤...

Vince_
2019/06/24
0
0
Babel 插件开发手册(官方)

这篇文档涵盖了如何创建 Babel 插件等方面的内容。 这本手册提供了多种语言的版本,查看 自述文件 里的完整列表。 目录 介绍 基础 抽象语法树(ASTs) Babel 的处理步骤 解析 转换 生成 遍历...

ZKL
2019/06/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一名时尚艺术家转行到科技行业的历程

Serverless 团队新成员 Charmmie 是从高级时装行业转行到技术领域的,本文是她的故事,太酷了。 我是一名艺术家、时尚行业从业者。讲真的,我从没想过自己有一天会像现在这样,坐在旧金山一家...

腾讯云Serverless
32分钟前
29
0
[算法] 刷题-数据结构

索引 最小栈 全O1结构 LRU 题解 最小栈 class MinStack: def __init__(self): """ initialize your data structure here. """ self.stack = list() ......

a_zphoenix
33分钟前
29
0
发现 | 友信金服旗下好分期违规套路贷,资金端人人贷会何去何从?

来源 | 复利频道 作者 | 赛闻 去年,P2P网贷行业曾因资产端涉及严重套路贷等问题,被监管进行了严厉打击。这导致多家P2P平台,例如花生米富、金蛋理财发生爆雷,前者高管目前仍在拘押中,后者...

镭射财经
37分钟前
34
0
python3 的tkinter和pygame自制音乐播放器的程序解析

感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30780.html 1.说明: 1.1 推荐环境:python3.8、微软vscode编辑器、pygame模块 1.2 熟悉tkinter的相关布局,gif导入、图片导入、路径...

曹长卿
45分钟前
21
0
Gson的使用和注解

目前比较流行的处理json数据的工具是Jackson和Fastjson,只有少数的公司使用Gson(一些公司对外部插件的安全性要求问题,如某些银行),这里对Gson的使用作个记录。 1、引进Gson jar包 <dep...

Lion华
46分钟前
32
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部