第 66 题:ES6 代码转成 ES5 代码的实现思路是什么?
Babel 是一个广泛使用的转码器,babel 可以将 ES6 代码完美地转换为 ES5 代码,所以我们不用等到浏览器的支持就可以在项目中使用 ES6 的特性。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
Babel 是一个广泛使用的转码器,babel 可以将 ES6 代码完美地转换为 ES5 代码,所以我们不用等到浏览器的支持就可以在项目中使用 ES6 的特性。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
ES6 代码转成 ES5 代码的实现思路是什么
关于AST
AST的全称是abstract syntax tree,中文名叫抽象语法树,假设有一个函数,
这段代码被解析成的ast树就是
这样看起来还不是很直观,其实上面的树就等于
有了这个json后,就可以对代码进行操作了。在没有树的情况下,如果要对文件里的某一个语句进行替换的话,一般就是全局
搜索然后replace,这样有可能影响到别的代码,但是有了树后,就可以对这个json进行操作,精确地去修改某个对象的属性,也就不会影响到别的代码了。所以babel转换ES6的核心,就是在ast中按照一定的规则取修改json里的属性和方法,然后再把tree转换成代码
ES6转ES5分为以下两种情况
1.语法转换
ES6语法通过babel等工具为ES5语法,本质是将ES6语法转AST(抽象语法数——对编程语言编写的程序的一种描述)再将AST转为ES5语法代码;例如:let,const转换为var,箭头函数转换为function函数声明等
2.API转换
采用babel-polyfill等工具对ES5中不存在的API(包括Set等ES6中新的数据结构)做修复,例如:
Array.prototype.includes
Set
Map
等在ES5中不存在,需要用相应的ES5代码实现这些API补充说明
script
style
template
再走上面的ES6转ES5流程这问的是问题么?
你说的是普通开发者的思路?
还是babel作者的思路啊??
涉及到的主要是AST相关的内容,AST(Abstract Syntax Tree)中文叫抽象语法树,是用来表示源代码语法的一种树形结构,树上的每个节点都代表源代码的一种结构。AST在我们日常应用中非常广泛,我们的代码高亮,代码检查等都是依靠的AST。
那么ES6转ES5的思路,其实就是在处理AST的过程中进行操作。转化代码的流程一般分为三步
现在一般使用的就是bable转ES6,具体的ES6转ES5在第二步中的逻辑,那就得看bable中转ES6的
babel-preset-es2015
对AST进行操作的源码了借用babel转换思想,将es6解析成AST,然后按照统一规则转换修改AST,再将AST解析成es5
ES6 代码转换成 ES5 的思路大家都讲的差不多,我来做个补充。
Babel 将把 ES6 转成 ES5 第二步,从 Babel 6.0 开始,就不再对代码进行转换。现在 Babel 只负责parse 和 generate 流程,也就是专注于解析和生成阶段。转换代码的 transform 过程全都交给bable插件去做了。
我们的项目里的
.babelrc
文件就是用来配置babel处理的,常有plugins 与 presets
配置项,当他们同时存在的时候,先执行plugins
从上到下,在执行presets
从左到右。说说我的理解哦
es6比es5多出来的部分分两类
一类是语法,如箭头函数,解构;
一类是新的类、新的类方法、新的实例方法,如:Promise, Array.from, Array.prototype.find
babel在做语法转换的时候,通过抽象语法树来实现代码层面的翻译。
比如将
const fn = () => {
Array.isArray([1, 2, 3]);
};
转成
"use strict";
var fn = function fn() {
Array.isArray([1, 2, 3]);
};
对于新的类、类方法,实例方法,基本就是polyfill,或者polyfill加上代码转换。
拿Array.from来说,只需要使用es5的语法,自己实现一遍Array.from,就可以用不改动源代码而使用Array.from这个es6的api了,@babel/polyfill这个包就是做这事儿的。
复杂点的Promise在babel转译的时候,不仅会调整源代码,还需要引入@babel/polyfill。有时候会遇到regeneratorRuntime is not defined这个报错,原因是源代码中Promise部分被转译了,转译后用到的regeneratorRuntime在@babel/polyfill中,但@babel/polyfill没被引入。
把 ES6 代码转成 ES5 代码的实现思路可以分成三步:
喔,不对,原谅我开了个玩笑,嗯,有点冷……
回到正题上来,说到 ES6 代码转成 ES5 代码,我们肯定会想到 Babel。所以,我们可以参考 Babel 的实现方式。
那么 Babel 是如何把 ES6 转成 ES5 呢,其大致分为三步:
基于此,其实我们自己就可以实现一个简单的“编译器”,用于把 ES6 代码转成 ES5。
比如,可以使用
@babel/parser
的parse
方法,将代码字符串解析成 AST;使用@babel/core
的transformFromAstSync
方法,对 AST 进行处理,将其转成 ES5 并生成相应的代码字符串;过程中,可能还需要使用@babel/traverse
来获取依赖文件等。对此感兴趣的可以看看这个。如果有误,希望可以帮忙指出来,多谢。
题目说的是 ES6,所以不考虑
.jsx
、.ts
这类 js 拓展语言。ES6 转 ES5 目前行业标配是用
Babel
,转换的大致流程如下:如果不用工具,纯人工的话,就是使用或自己写各种 polyfill 了。
将ES6的代码转换为AST语法树,然后再将ES6 AST转为ES5 AST,再将AST转为代码