关闭

babel的初步了解

时间: 2018-12-25阅读: 1014标签: 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的协同开发,我也大概花了一张图表示他们之间的关系,但里面的原理,我后续会再去研究,研究好再分享一下:


来源:https://segmentfault.com/a/1190000017499449

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1691

Babel 7 转码的正确姿势

Babel 转码的配置是每位前端童鞋在日常工作中都会遇到的。刚开始我也是在网上搜索各种配置方法,升级到 Babel 7 的时候又折腾了一把,所以决定把自己的心得和理解记录下来,希望能帮助到有需要的童鞋。

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

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

webpack中配置babel

因为在webpack中,默认只能处理一部分es6的语法,一些更高级的es6和es7语法webpack不能处理,这时就需要第三方的loader即babel来帮助webpack来处理这些高级的语法

Babel是什么?

Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。下面列出的是 Babel 能为你做的事情

使用@babel/preset-typescript取代awesome-typescript-loader和ts-loader

谈@babel/preset-typescript的优越性之前,还是先说下awesome-typescript-loader方案是如何对TypeScript进行处理的。首先我们需要知道TypeScript是一个将TypeScript转换为指定版本JS代码的编译器

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

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

不容错过的 Babel7 知识

对 Babel 的配置项的作用不那么了解,是否会影响日常开发呢?老实说,大多情况下没有什么影响。不过呢,还是想更进一步了解下,于是最近认真阅读了 Babel 的文档,外加不断编译验证

Babel-loader,babel-core和babel-preset之间是什么关系

`babel-loader` 是一个 npm 包,它使得 webpack 可以通过 babel 转译 JavaScript 代码。babel 的功能在于「代码转译」,具体一点,即将目标代码转译为能够符合期望语法规范的代码。在转译的过程中

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

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

babel是怎样工作的

第一步可以说是是编译器的基本功能,通过解析器将原始代码转换成抽象语法树(AST),顾名思义就是描述语法的数据结构,一般在这一步编译器都会做两件事:语法分析与语义分析。语法分析是去定义原始代码中的内容是否应该被认为一个单位,然后是语义分析

点击更多...

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