-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Babel: 关于 Babel 那些事儿 #90
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
关于 Babel 那些事儿
⭐ 什么是Babel?
Babel
是一个JavaScript
编译器, 用于将ES2015+
的代码转换为向后兼容的JavaScript
语法, 以便能够在当前版本或者旧版本的浏览器中运行. 简单来说, Babel 的工作⭐ Babel 的基本原理
Babel
的原理: 核心就是 AST (抽象语法树), 首先将源码抽象成语法树, 然后对语法树进行处理生成新的语法树,最后将新语法树生成新的 JS 代码.parsing(解析)
===>transforming(转换)
==>generating(生成)
Babel
只负责转译编译新标准引入的新语法,比如Arrow function
,Class
,ES Module
, 不会编译原生对象新引入的方法和API, 比如Array.inclues
,Map
,Set
等, 这些靠Polyfill
来解决.⭐ Babel 的使用
运行 babel 所需的基本环境
babel/cli
===>npm install i -S @babel/cli
@babel/core
===>npm install i -S @babel/core
配置 Babel 配置文件, Babel 的配置文件有四种形式
⭐ Babel Plugins (插件)
插件是用来定义如何转换你的代码的. 在
Babel
的配置项中填写需要使用的插件名称,Babel
在编译的时候就会去加载node_modules
中对应的npm
包, 然后编译插件对应的语法. 以.babelrc
为例:插件执行顺序
Presets
) 前运行Babel
在进行AST
遍历的时候会先调用transform-decorators-legacy
插件中定义的转换方法, 然后再调用transform-class-properties
中的方法.插件传参
插件名称
@babel/plugin-XX
, 可以使用短名称@babel/XX
, 如果为babel-plugin-xx
, 可以直接使用xx
自定义插件
⭐ 预设 (Presets)
预设
就是一堆插件(Plugin
)的组合, 从而达到某种转译的能力, 就比如react
中使用到的@babel/preset-react
, 它就是下面几种插件的组合.预设(Presets)的执行顺序
插件
的执行顺序是从左往右
预设
的执行顺序恰从右往左
常见的几种预设
@babel/preset-stage-xxx
:@babel/preset-stage-xxx
是 ES 在不同阶段语法提案的转码规则而产生的预设, 随着被批准为 ES 新版本的组成部分而进行相应的改变(例如 ES6/ES2015),提案分为以下几个阶段💛 2):
@babel/preset-es2015
:preset-es2015
是仅包含ES6
功能的Babel
预设. 实际上在Babel7
出来后上面提到的这些预设stage-x
,preset-es2015
都可以废弃了, 因为@babel/preset-env
出来一统江湖了.🧡 3):
@babel/preset-env
: 前面两个预设是从ES
标准的维度来确定转码规则的, 而@babel/preset-env
是根据浏览器的不同版本中缺失的功能确定代码转换规则的, 在配置的时候我们只需要配置需要支持的浏览器版本就好了,@babel/preset-env
会根据目标浏览器生成对应的插件列表然后进行编译:在默认情况下
@babel/preset-env
支持将 JS 目前最新的语法转成 ES5, 但需要注意的是, 如果你代码中用到了还没有成为 JS 标准的语法, 该语法暂时还处于stage
阶段, 这个时候还是需要安装对应的stage
预设, 不然编译会报错@babel/preset-env
在默认情况下和preset-stage-x
一样只编译语法, 不会对新方法和新的原生对象进行转译, 例如:⭐ Polyfill 垫片
polyfill
的翻译过来就是垫片, 垫片就是垫平不同浏览器环境的差异, 让大家都一样@bable/polyfill
: @babel/polyfill 模块可以模拟完整的 ES5 环境. (npm install --save @babel/polyfill
)@babel/polyfill
不是在 Babel 配置文件中配置, 而是在我们的代码中引入.useBuiltIns
这里是require("@babel/polyfill")
将整个@babel/polyfill
加载进来了, 但是在这里我们需要处理Array
.includes
和Promise
就好了, 如果这样就会导致我们最终打出来的包体积变大, 显然不是一个最优解. 要是能按需加载就好了. 其实 Babel 早就为我们想好了.@babel/preset-env
, 他出现的目的就是实现民族大统一, 连stage-x
都干掉了, 又怎么会漏掉Polyfill
这一功能, 在@babel/preset-env
的配置项中提供了useBuiltIns
这一参数, 只要在使用@babel/preset-env
的时候带上他,Babel
在编译的时候就会自动进行Polyfill
, 不再需要手动的在代码中引入@babel/polyfill
了, 同时还能做到按需加载其他
@babel/plugin-transform-runtime
: 可以让 Babel 在编译中复用辅助函数, 从而减小打包文件体积The text was updated successfully, but these errors were encountered: