habc0807 / fe-interview

BAT、TMD等各大厂中高级、资深前端面试题整理
36 stars 4 forks source link

Babel是如何将ES6及以上版本的代码转换为ES5的? #17

Open habc0807 opened 4 years ago

habc0807 commented 4 years ago
AMY-Y commented 4 years ago
babel的转译过程分为三个阶段:parsing(解析)、transforming(转化)、generating(生成)

babel转译的具体过程如下:
ES6代码输入 ==》 babylon进行解析 ==》 得到AST==》 plugin用babel-traverse对AST树进行遍历转译 ==》 得到新的AST树 
==》 用babel-generator通过AST树生成ES5代码

babel将es6+(指es6及以上版本)分为语法层和api层:
语法层: let、const、class、箭头函数等,这些需要在构建时进行转译,是指在语法层面上的转译,(比如class...将来会被转 
译成var function...)
api层:Promise、includes、map等,这些是在全局或者Object、Array等的原型上新增的方法,它们可以由相应es5的方式重 
新定义

babel对这两个分类的转译的做法是不一样的,需要给出相应的配置

语法层可以使用插件preset进行转译;api层可以使用polyfill进行转译。同时preset-env的useBuiltIns属性可以控制加载代码中用到的polyfills

@babel/plugin-transform-runtime插件:
实现对辅助函数的复用,解决转译语法层时出现的代码冗余
解决转译api层出现的全局变量污染

作者:no_bug 链接:https://juejin.im/post/6844904199554072583 来源:掘金

habc0807 commented 4 years ago

看到这个问题的第一眼,我们需要先知道 Babel是什么?Babel解决了什么问题?它又是如何解决的呢?

首先Babel是一个JavaScript的编译器,主要来解决ESnext新特性浏览器不能支持的问题的。其次Babel是如何解决这个问题的呢?重点来了,任何一个编译器的工作流程大致可以分为以下三步:

Bable主要做解析源文件和生成新文件,转换都交给了Bable插件们处理。Bable为每一个新语法都提供了一个插件。通常使用 @babel/preset-env插件集,避免一个一个的配置,该插件包含大部分的ESnext的新特性,不包含的需要单独引入需要的 polyfill

列举babel的主要库: