当前位置: 首页 > news >正文

[Javascript] Babel转译原理

概述

编译与转译

编译(Compile):通常是 高级语言 → 机器码/字节码,比如 C → 汇编。

转译(Transpile):通常是 一种语言的源代码 → 另一种语言的源代码,保持抽象层级接近。

前端中常见的转译操作,如下:

  • ES6 -> ES5
  • TS -> JS
  • SASS -> CSS

代码转译示例

Babel库是目前非常流行的 Javascript Transpiler,即JS转译器。

// ES6
let foo = 123// ES5
var foo = 123

Babel转译演示

  1. 安装
npm install @babel/core @babel/cli @babel/preset-env
  1. 创建babel.config.json
{"presets": ["@babel/preset-env"],"plugins": []
}
  1. babel转译
babel src --out-dir dist
  1. plugins使用
{"presets": [],"plugins": ["@babel/plugin-transform-block-scoping"]
}

转译的原理

核心步骤

  • parse:通过 parser 把源码转成抽象语法树(AST)
  • transform:遍历 AST,调用各种 transform 插件对 AST 进行增删改
  • generate:把转换后的 AST 输出成目标代码

可视化工具

AST explorer 是一个 AST 可视化工具,通过它可以查看各种编程语言代码解析后的 AST 结构,帮助开发者更直观地观察代码与 AST 节点树具体节点的对应关系。

查看代码:https://astexplorer.net/#/gist/2335b6e2175368119301cc8edad3642f/a2cefc03c9451ed387caebe338a2c5e99b501923

parse详解

通过 parser 把源码转成抽象语法树(AST)

  • 词法分析
  • 语法分析

词法分析

将整个代码字符串分割成最小语法单元数组。这些词法单元(tokens)包括数字,标点符号,运算符等,这些词法单元之间都是独立的。

// 源代码
let foo = 123// 词法分析转换后
const tokens = [{"type": { "label": "name" }, "value": "let", "start": 0, "end": 3},{"type": { "label": "name" }, "value": "foo", "start": 4, "end": 7},{"type": { "label": "=" }, "value": "=", "start": 8, "end": 9 },{"type": { "label": "num" }, "value": 123, "start": 10, "end": 13  },{"type": { "label": "eof" }, "start": 13, "end": 13}
]

注:可视化工具查看分割的tokens集合。

利用状态机,简单实现词法分析:

:::info
01demo

:::

语法分析

将词法分析出来的 tokens 按照不同的语法结构如声明语句、赋值表达式等转化成有语法含义的抽象语法树结构。

AST 是对源码的抽象,字面量、标识符、表达式、语句、模块语法、class 语法都有各自的 AST。

  • Literal:字面量
  • Identifer:标识符
  • statement:语句
  • Declaration:声明
  • Expression:表达式
  • Class:类
  • Modules:模块
  • 其他
    • program:整个程序的节点
    • directives:指令,例如:"use strict"
    • comments:注释
const tokens = [{ type: { label: 'name' }, start: 0, end: 3, value: 'let' },{ type: { label: 'name' }, start: 4, end: 7, value: 'foo' },{ type: { label: '=' }, start: 8, end: 9, value: '=' },{ type: { label: 'num' }, start: 10, end: 13, value: 123 },{ type: { label: 'eof' }, start: 13, end: 13 }
]const AST = {"type": "Program","start": 0,"end": 13,"body": [{"type": "VariableDeclaration","start": 0,"end": 13,"declarations": [{"type": "VariableDeclarator","start": 4,"end": 12,"id": {"type": "Identifier","start": 4,"end": 7,"name": "foo"},"init": {"type": "NumericLiteral","start": 10,"end": 13,"value": 123}}],"kind": "let"}]
}

如何处理复杂的语法分析呢,代码如下:

if (true) {if (true) {let foo = 123}
}const tokens = [{ type: { label: 'if' }, start: 0, end: 2, value: 'if' },{ type: { label: '(' }, start: 3, end: 4 },{ type: { label: 'true' }, start: 4, end: 8, value: 'true' },{ type: { label: ')' }, start: 8, end: 9 },{ type: { label: '{' }, start: 10, end: 11 },{ type: { label: 'if' }, start: 14, end: 16, value: 'if' },{ type: { label: '(' }, start: 17, end: 18 },{ type: { label: 'true' }, start: 18, end: 22, value: 'true' },{ type: { label: ')' }, start: 22, end: 23 },{ type: { label: '{' }, start: 24, end: 25 },...{ type: { label: '}' }, start: 46, end: 47 },{ type: { label: '}' }, start: 48, end: 49 }
]
如何保证正确的嵌套关系,利用数据结构中的堆栈来实现

:::info
02demo

:::

transform详解

对AST对象进行遍历,遍历的过程中处理到不同的 AST 节点会调用注册的相应的 visitor 函数,visitor 函数里可以对 AST 节点进行增删改,返回新的 AST。

  • traverser 遍历(深度优先遍历)
  • transformer 转换

:::info
03demo

:::

generate详解

AST 根节点进行递归的字符串拼接,就可以生成目标代码的字符串。

:::info
04demo

:::

自定义Babel插件

// my-plugin.js
module.exports = ({ types: t }) => {return {name: "myPlugin",visitor: {VariableDeclaration(path) {path.node.kind = "var";},Identifier(path) {path.node.name = "bar";},},};
};
http://www.sczhlp.com/news/56372/

相关文章:

  • 9.2 os模块
  • 越秀网站建设设计设计的好网站
  • getc - 单字符读取 fgets - 字符串/行读取 fread - 二进制数据读取 fscanf - 格式化文本读取
  • 个人备案网站服务内容中小型网站建设市场
  • 开源网站下载上海官网制作
  • wordpress添加媒体无反应西安全网优化
  • 深圳网站建设 设计卓越wordpress 字体 服务器
  • 响应式网站怎么制作国内规模大的建站公司
  • 秋佐科技公司网站头像在线制作网站
  • 舆情网站入口app开发自学
  • [Javascript] 并发与并行
  • Vim常用操作速查表
  • 网站与网页之间的区别是什么意思logo制作软件免费版
  • 重庆网站建设外贸安徽六安彩礼一般给多少
  • 网站再就业培训班吉林电商网站建设费用
  • iis网站压缩网页制作免费的素材网站
  • wordpress 元描述厦门seo排名收费
  • 做app的网站有哪些功能吗wordpress+widget+开发
  • vs2010网站开发示例网站建设策划方
  • 在线购物网站的设计与实现wordpress 按时间类别
  • 上海专业网站建设wordpress注册去掉电子邮件
  • wordpress 大学主题seo推广地域的设置策略
  • 山西建设网站企业学信网为什么不承认开放大学
  • 软件下载地址
  • 如何做网站视频女生做seo网站推广
  • 邯郸做网站推广费用家在深圳龙华
  • 网站建设中gif秦皇岛建设银行
  • 南昌网站建设优化公司排名比特币支付网站建设
  • 怎么建立一个网站网页网站开发设计工作前景
  • Python 表格数据处理:pandas与openpyxl