babel原理_浅谈babel原理以及使用

最近项目中遇到再安卓5.0以下的兼容问题,最后查了资料发现没有引入babel-polyfill的原因导致。后来就详细了解并整理了一下babel相关的知识点。

Babel包的构成

核心包

babel-core :是babel转译器本身,提供转译的API,例如babel.transform等,webpack的babel-loader就是调用这些API完成转译的

babylon :js的词法解析器

babel-traverse :用于对AST(抽象语法树Abstract Syntax Tree)的遍历

其他

babel-types :用于检验,构建和变更AST的节点

babel-helpers :一系列预制的babel-template函数,用于提供给一些plugins使用

babel-template :辅助函数,用于从字符串形式的代码来构建AST树节点

babel-code-frame :用于生成错误信息,打印出错误点源代码帧以及指出出错位置

babel-register :通过绑定node.js的require来完成自动编译

babel-polyfill :JS标准新增的原生对象和API的shim,实现上仅仅是core-js和regenerator-runtime两个包的封装

babel-runtime :类似于polyfill,但是不会污染全局变量

babel的配置

一般常见的还是直接通过编写.babelrc,也推荐这么用,当然你也可以使用命令行的形式。

配置字段(这里以vue的官方架子里面的字段为例)

env:可以对BABEL_ENV或者NODE_ENV指定的不同的环境变量,进行不同的编译操作,优先获取BABEL_ENV环境变量,然后NODE_ENV,最后默认development

plugins:使用的插件列表

presets:使用的preset列表,常见的es20xx,stage-x,以及env等

comments:编译过程是否产生注释,默认为true

配置文件的查找

babel会从当前转译的文件所在目录下查找配置文件,如果没有找到,就顺着文档目录树一层层往上查找,一直到.babelrc文件存在或者带babel字段的package.json文件存在为止。

babel的工作原理

ES6代码输入 ==》 babylon进行解析 ==》 得到AST

==》 plugin用babel-traverse对AST树进行遍历转译 ==》 得到新的AST树

==》 用babel-generator通过AST树生成ES5代码

babel转译有一点需要注意: babel只是转译新标准引入的语法,比如ES6的箭头函数转译成ES5的函数;而新标准引入的新的原生对象,部分原生对象新增的原型方法,新增的API等(如Proxy、Set等),这些babel是不会转译的。需要用户自行引入polyfill来解决。

polyfill

polyfill其实就是对core-js和regenerator runtime进行了包装,为es2015+提供了一个环境垫片,让你可以使用新标准引入的各种新特性

polyfill的使用方法

// 首先安装包文件

npm install babel-polyfill --save-dev

// 在文件的入口处引入

import 'babel-polyfill'

// 在webpack.config.js中

module.exports = {

entry:["babel-polyfill","./app/js"]

}

这里的方法会将全部的环境都导入,但是polyfill的文件比较大,即便是压缩后也可能达到80kb,在移动端我们是不希望引入这么大的辅助文件(比vue大得多),所以我们希望实现按需引入,如果我们明确知道自己需要转译哪些API,我们可以借助于 core-js 实现按需引入。

1、类似于polyfill,将所有的特性添加到全局环境,默认方式

require('core-js') // 引用到全局中,这种方式将所有特性引入

2、库的形式引入,这种也是引入所有的特性,只是不会污染全局变量

let core = require('core-js/library')

3、只引入shim,只包含标准特性,其实和polyfill一样

require('core-js/shim')

core-js 按需引入的使用方法

// 全局引入

require('core-js/es6/promise')

require('core-js/fn/object/assign')

// 库的形式引入

import Promise from 'core-js/es6/promise'

import assign from 'core-js/fn/object/assign'

Object.assign = assign

polyfill与runtime的区别

最主要的区别就是polyfill引入后,会将新的原生对象、API这些都直接引入到全局环境,这样就会污染全局变量,这也是polyfill的缺陷。所以就轮到babel-runtime上场了。

transform-runtime和babel-runtime

transform-runtime是将js中使用到新的原生对象和静态方法转译成对babel-runtime的引用,而其中babel-runtime的功能其实最终也是由core-js来实现的,其实真正的核心是上面所讲的core-js,其他的都是包装。

总结

babel的使用其实不难,只需要理解各个依赖关系就可以了,明白各个包以及插件分别用来干嘛就可以啦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值