babel的初步了解
前段时间开始研究ast,然后慢慢的顺便把babel都研究了,至于ast稍后的时间会写一篇介绍性博客专门介绍ast,本博客先介绍一下babel的基本知识点。
- 背景:
由于现在前端出现了很多非es5的语法,如jsx,.vue,ts等等的格式和写法,如果要在浏览器的设备上识别并执行,需要额外将这些非传统格式的语法转成传统的es5格式,而babel插件,就是用来将非es5格式的语法转成es5语法。
babel其实是一个解释器,它主要讲进行中的代码分为三个阶段执行:解释,转换,生成。其中babel插件或者其他插件都是在转换阶段起作用。
- babel核心包:
babel既然是个解释器,那么就会拥有解释,遍历,以及生成的一系列工具和api:
1)babylon:babel里面用来将js代码词法分析,生成ast,他的结构有些像acron,它的返回的结构里面包含着ast和tokens。
require("babylon").parse("code", {
// parse in strict mode and allow module declarations
sourceType: "module",
plugins: [
// enable jsx and flow syntax
"jsx",
"flow"
]
});
sourceType: module表示的是在严格模式下解析并且允许模块定义(即能识别import和expor语法);script识别不了。
2)babel-traverse:功能就像estraverse一样,主要是给plugin提供遍历ast节点的功能;
var babylon = require('babylon');
var result = babylon.parse(code, { sourceType: "module",});
console.log('result:', result);
import traverse from "babel-traverse";
traverse(result, {
enter(node) {
console.log(node);
}
});
3)babel-generator:将ast生成js代码;
var babylon = require('babylon');
var result = babylon.parse(code, { sourceType: "module",});
console.log('result:', result);
import traverse from "babel-traverse";
import generate from 'babel-generator';
traverse(result, {
enter(node) {
console.log(node);
}
});
var conde1 = generate(result);
console.log('generate:', conde1);
- babel工具包:
要完成复杂的转换工作,单靠核心包是不能完成的,所以必要还要依赖于其他工具包辅助。
1)babel-types:包含着ast中的所有类型,可以生成一个ast的节点,然后替换真是ast的节点,从而改变ast的内容(ast工具库,类似于lodash,具有校验,创建和转换ast的方法)。
import * as t from "babel-types";
console.log(t.stringLiteral("my-module"));
语法:t.anyTypeAnnotation(内容) // 最终返回一个类型的对象
2)babel-template:可以通过字符串的形式生成一个ast;
import template from "babel-template";
const buildRequire = template(`
var IMPORT_NAME = require(SOURCE);
`);
const ast2 = buildRequire({
IMPORT_NAME: t.identifier("myModule"),
SOURCE: t.stringLiteral("my-module")
});
console.log('ast2', ast2);
3)babel-helps: 主要是用来协助babel转换;
4)babel-core-frame: 主要是用来将错误信息打印出来;
5)babel-cli:babel的命令行工具,通过命令行对js代码进行转译;
6)babel-register: 因为babel工具文件,插件里面使用了很多require,而 该文件可以将node中的require于babel中的require绑定,从而可以使用require引入文件;
7)babel-plugin-xxx: 在转换过程中使用的插件;
8)babel-plugin-transform-xxx: 在transerform过程中使用到的插件;
(.babelrc文件:该文件会在babel编译过程中,自动配置babel的参数,babel的运行环境--env,babel的设置---preset,babel的所需要用到的插件---plugins等)
9)babel-core:该核心包包含着babel的核心(babel-lon,babel-traverse,babel-generate),提供了更多更友善的api给开发者使用。
- babel编译原理:
编译器就是讲高级的语言或者语法,编译成更进阶机器识别的语言和语法;
babel其实更像一个转译器,因为它主要是将高级的js语法转成低级的语法;
他们两者虽然有区别,但有很多相似之处(都是经历三个过程:解析,处理,生成);
以es6转成es5为例:
ES6代码输入 ==》 babylon进行解析 ==》 得到AST ==》 plugin用babel-traverse对AST树进行遍历转译 ==》 得到新的AST树 ==》 用babel-generator通过AST树生成ES5代码
- babel-pollfill,babel-runtime,transfer-runtime的区别:
babel-pollfill是针对于应用和页面范围内,对新的对象和新的语法进行兼容,主要是通过一些辅助函数进行兼容新的语法,但如果针对外部的库使用,就会产生污染全局环境的影响,一般对项目代码使用;
babel-runtime是对于外部插件和库的语法兼容,能将新的对象和语法,通过在运行时,把对应的可识别的语法和对象匹配出来并进行转换,从而显示在运行时进行语法降级兼容,且不会产生全局污染,一般对外部的插件使用;
transfer-babel是对babel-runtime进行封装,新的语法,对象能通过该插件,换种形式引用runtime的东西;
(其实runtime,pollfill都是建立在core-js之上的)。
对于babel的插件,主要是因为生成的ast的底层中有一个accept方法,专门用来接收visitor(插件)访问者对象,然后在visitor中定义各种节点类型的操作-visite,每个visite都可以接受一个path参数(节点信息,节点和位置信息的对象,其包含很多有用的方法),在visit中处理path,从而实现转换的作用。
const result = babel.transform(code, {
plugins: [{
visitor
}]
})
console.log(result.code);
至于visitor后续会详细介绍。
整个babel的结构图,我大概花了一张图表示出来:
而babel和webpack的协同开发,我也大概花了一张图表示他们之间的关系,但里面的原理,我后续会再去研究,研究好再分享一下:
以上是我对babel的初步理解,如果有不正确的地方,欢迎指出。
来源:https://segmentfault.com/a/1190000017499449
babel的初步了解的更多相关文章
- 利用Babel来转化你的ES2015脚本初步
我们在前面已经安装和学习过babel 安装babel-cli 这是babel解释器的客户端主程序 npm install -g babel-cli 安装”编译”插件(babel的JSX语法转换器) n ...
- 《前端之路》之 Babel 下一代 JavaScript 语法编译器
写本章的内容的出发点主要是 为了对于之前关于 JS 版本的一个总结,在之前的开发中,我们始终对于 ECMAScript 的版本的更新不够重视,以至于在后面的 开发过程中,我们始终会被各种新奇的语法打断 ...
- babel 7 简单升级指南
babel 7 babel 7 发布两天了,试着对当前项目更新了下,仅此记录分享 主要改动参考 官方博客 官方升级指南 主要升级内容 不再支持放弃维护的 node 版本 0.10.0.12.4.5 使 ...
- babel使用入门以及使用webpack+babel来"编译"你的JS代码
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5,从而在现有的环境中执行. 这是一个开端,以后遇到问题,也会持续记录. 一.babel配置 官网有更详细的配置教程:https://www. ...
- babel速览
babel babel初衷 在es6出现之后,由于此版本的巨大改变,给人们带来了很多革命性的技术支持,但是当时很多浏览器对es6支持有限,babel就是为了达到写最新的语法,可以在任意浏览器运行而出现 ...
- babel plugin和presets是什么,怎么用?
https://www.fullstackreact.com/articles/what-are-babel-plugins-and-presets/ 当开发react或者vuejs app时,开发者 ...
- Babel配置中的presets、plugins、各个阶段stage的含义
什么是Babel Babel 官方文档: https://babeljs.io/ Babel 中文文档:https://www.babeljs.cn/ 我们知道各个浏览器对JavaScript版本的支 ...
- 初步认识微前端(single-spa 和 qiankun)
初步认识微前端 微前端是什么 现在的前端应用,功能.交互日益复杂,若只由一个团队负责,随着时间的推进,会越来越庞大,愈发难以维护. 微前端这个名词,第一次提出是在2016年底.它将微服务(将单一应用程 ...
- 移动端之Android开发的几种方式的初步体验
目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...
随机推荐
- 序列式容器————dequeue
#include <deque> 双端队列,可以在队头队尾进行入队出队操作 deque<int> q; q.empty(); q.push_front(s);//将s插入到队头 ...
- c++内置变量类型
1,各种变量占据的内存空间 char:1个字节,也可亦作为0-255的数值参与运算 一般来说,静态存储区的自动赋初值,动态则不自动(貌似也不对,因为非内置变脸的类型,也都调用了默认构造函数进行初始化) ...
- js,正则实现金钱格式化
https://blog.csdn.net/qq_36279445/article/details/78889305 https://github.com/jawil/blog/issues/30
- ArrayList类源码浅析(二)
1.removeAll(Collection<?> c)和retainAll(Collection<?> c)方法 第一个是从list中删除指定的匹配的集合元素,第二个方法是用 ...
- nginx中lua主动设置Content-Length
最近发现lua调用ngx.say和ngx.print 默认返回的HTTP头是trunk模式的,通常情况下是很好的,没有什么问题:但是要提供给其他人回源的时候就有问题了,特别是我要给slice模块回源, ...
- docker部署Javaweb项目(jdk+tomcat+mysql)
步骤一:在主机下载安装docker,参照Centos7上安装docker 步骤二:下载Linux版本的JDK1.6和Tomcat6.0(其他项目若依赖其他版本的运行环境可选择另外版本下载),通过sec ...
- PLSQL导出还原数据库
1 导出存储过程,触发器,序列等所有用户对象.(备份) 导出所有的表,存储过程,触发器,序列等所有的创建语句(.sql文件) 在PL/SQL Developer的菜单Tools(工具) => ...
- 安装 Windows 系统在 NVMe 规范的 M.2 接口的固态硬盘(SSD)上
作为一个程序员很重要的一项技能就是装系统 @_@,以前我都是随便用网上的工具做个系统盘,每次要用直接随手就搞好了,节省大家时间. 但最近同事装了个贼小的固态,然后我启动盘里的系统果断识别不出来他的固态 ...
- RocketMQ 主从同步
RocketMQ 的主和从一直在使用 nio 进行数据同步: master master 监听端口 org.apache.rocketmq.store.ha.HAService.AcceptSocke ...
- 红帽虚拟化RHEV-安装RHEV-M
目录 目录 前言 软件环境 时间同步 更新系统 安装并配置RHEV-M 添加域并为用户授权远程登陆 安装rhevm报告 安装Spice协议 最后 前言 在红帽虚拟化RHEV-架构简介篇中介绍了RHEV ...