第 66 题:ES6 代码转成 ES5 代码的实现思路是什么?

发布于 2022-08-15 16:18:40 字数 80 浏览 177 评论 10

Babel 是一个广泛使用的转码器,babel 可以将 ES6 代码完美地转换为 ES5 代码,所以我们不用等到浏览器的支持就可以在项目中使用 ES6 的特性。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

№⒈╰謸气贵蔟╮ 2022-05-04 13:51:57

ES6 代码转成 ES5 代码的实现思路是什么

  • 把代码字符串解析成AST(抽象语法树)
  • AST就是一个json,按照一定规则把这个json里ES6部分的东西转换成ES5的
  • 再把修改后的AST转换成代码

关于AST

AST的全称是abstract syntax tree,中文名叫抽象语法树,假设有一个函数,

function hello(a, b, c){ 
}

这段代码被解析成的ast树就是

type: Program
-
body
-
#1
type: FunctionDeclaration
-
id
type: Identifier
name: hello
-
params
-
#1
type: Identifier
name: a
-
#2
type: Identifier
name: b
-
#3
type: Identifier
name: c
-
body
type: BlockStatement
body
generator: false
expression: false
async: false
sourceType: script

这样看起来还不是很直观,其实上面的树就等于

{
  "type": "Program",
  "body": [
    {
      "type": "FunctionDeclaration",
      "id": {
        "type": "Identifier",
        "name": "hello"
      },
      "params": [
        {
          "type": "Identifier",
          "name": "a"
        },
        {
          "type": "Identifier",
          "name": "b"
        },
        {
          "type": "Identifier",
          "name": "c"
        }
      ],
      "body": {
        "type": "BlockStatement",
        "body": []
      },
      "generator": false,
      "expression": false,
      "async": false
    }
  ],
  "sourceType": "script"
}

有了这个json后,就可以对代码进行操作了。在没有树的情况下,如果要对文件里的某一个语句进行替换的话,一般就是全局
搜索然后replace,这样有可能影响到别的代码,但是有了树后,就可以对这个json进行操作,精确地去修改某个对象的属性,也就不会影响到别的代码了。所以babel转换ES6的核心,就是在ast中按照一定的规则取修改json里的属性和方法,然后再把tree转换成代码

薄情伤 2022-05-04 13:46:30

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


补充说明

  • .vue文件通过webpack的vue-loader分析出script style template 再走上面的ES6转ES5流程
  • jsx通过babel插件转js语法再走ES6转ES5
  • ts通过tsc结合tsconfig.json直接转ES5
甜中书 2022-05-04 13:24:34

这问的是问题么?
你说的是普通开发者的思路?
还是babel作者的思路啊??

︶葆Ⅱㄣ 2022-05-04 13:23:48

涉及到的主要是AST相关的内容,AST(Abstract Syntax Tree)中文叫抽象语法树,是用来表示源代码语法的一种树形结构,树上的每个节点都代表源代码的一种结构。AST在我们日常应用中非常广泛,我们的代码高亮,代码检查等都是依靠的AST。

那么ES6转ES5的思路,其实就是在处理AST的过程中进行操作。转化代码的流程一般分为三步

  1. 将代码通过解释器转化为AST,可以通过 astexplorer 来查看代码对应的AST结构
  2. 通过一定的规则,去修改AST的结构(常见的比如转jsx,ES6转ES5都是在这一步进行操作)
  3. 将修改后的AST转化为普通代码

现在一般使用的就是bable转ES6,具体的ES6转ES5在第二步中的逻辑,那就得看bable中转ES6的babel-preset-es2015 对AST进行操作的源码了

别在捏我脸啦 2022-05-04 13:04:50

借用babel转换思想,将es6解析成AST,然后按照统一规则转换修改AST,再将AST解析成es5

梦萦几度 2022-05-04 12:07:31

ES6 代码转换成 ES5 的思路大家都讲的差不多,我来做个补充。

Babel 将把 ES6 转成 ES5 第二步,从 Babel 6.0 开始,就不再对代码进行转换。现在 Babel 只负责parse 和 generate 流程,也就是专注于解析和生成阶段。转换代码的 transform 过程全都交给bable插件去做了。

我们的项目里的 .babelrc 文件就是用来配置babel处理的,常有plugins 与 presets配置项,当他们同时存在的时候,先执行plugins从上到下,在执行presets从左到右。

走过海棠暮 2022-05-04 05:19:33

说说我的理解哦
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没被引入。

爱本泡沫多脆弱 2022-05-03 06:22:15

把 ES6 代码转成 ES5 代码的实现思路可以分成三步:

  • 打开冰箱
  • 把大象装进去
  • 关上冰箱

喔,不对,原谅我开了个玩笑,嗯,有点冷……

回到正题上来,说到 ES6 代码转成 ES5 代码,我们肯定会想到 Babel。所以,我们可以参考 Babel 的实现方式。

那么 Babel 是如何把 ES6 转成 ES5 呢,其大致分为三步:

  • 将代码字符串解析成抽象语法树,即所谓的 AST
  • 对 AST 进行处理,在这个阶段可以对 ES6 代码进行相应转换,即转成 ES5 代码
  • 根据处理后的 AST 再生成代码字符串

基于此,其实我们自己就可以实现一个简单的“编译器”,用于把 ES6 代码转成 ES5。

比如,可以使用 @babel/parserparse 方法,将代码字符串解析成 AST;使用 @babel/coretransformFromAstSync 方法,对 AST 进行处理,将其转成 ES5 并生成相应的代码字符串;过程中,可能还需要使用 @babel/traverse 来获取依赖文件等。对此感兴趣的可以看看这个

如果有误,希望可以帮忙指出来,多谢。

焚却相思 2022-04-30 12:00:34

题目说的是 ES6,所以不考虑 .jsx.ts 这类 js 拓展语言。
ES6 转 ES5 目前行业标配是用 Babel,转换的大致流程如下:

  1. 解析:解析代码字符串,生成 AST;
  2. 转换:按一定的规则转换、修改 AST;
  3. 生成:将修改后的 AST 转换成普通代码。

如果不用工具,纯人工的话,就是使用或自己写各种 polyfill 了。

笑叹一世浮▽沉 2022-04-30 03:11:30

将ES6的代码转换为AST语法树,然后再将ES6 AST转为ES5 AST,再将AST转为代码

~没有更多了~

关于作者

树深时见影

暂无简介

0 文章
0 评论
25 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文