前端应该掌握的编译基础(基于 babel)

开发息息相关

虽然 Babel 团队在各种哭穷,但是 Babel 始终是我们前端在开发中不可或缺的重要工具。
虽然我们只是 API 调用工,但是多了解一些总是会有好处的嘛 ☄️☄️☄️

什么是编译器?

编译器(compiler)是一种计算机程序,它会将某种编程语言写成的源代码(原始语言)转换成另一种编程语言(目标语言)。

源代码(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标代码(object code)→ 链接器(linker)→ 可执行文件(executables),最后打包好的文件就可以给电脑去判读运行了。

什么是解释器?

解释器(英语:interpreter),是一种计算机程序,能够把解释型语言解释执行。解释器就像一位“中间人”。解释器边解释边执行,因此依赖于解释器的程序运行速度比较缓慢。解释器的好处是它不需要重新编译整个程序,从而减轻了每次程序更新后编译的负担。相对的编译器一次性将所有源代码编译成二进制文件,执行时无需依赖编译器或其他额外的程序。

跟编译器的区别就是一个是边编译边执行,一个是编译完才执行。

高级语言编译器步骤

  1. 输入源程序字符流
  2. 词法分析
  3. 语法分析
  4. 语义分析
  5. 中间代码生成
  6. 机器无关代码优化
  7. 代码生成
  8. 机器相关代码优化
  9. 目标代码生成

V8 编译 JS 代码的过程

  1. 生成抽象语法树(AST)和执行上下文
  2. 第一阶段是分词(tokenize),又称为词法分析
  3. 第二阶段是解析(parse),又称为语法分析
  4. 生成字节码
  5. 字节码就是介于 AST 和机器码之间的一种代码。但是与特定类型的机器码无关,字节码需要通过解释器将其转换为机器码后才能执行。
  6. 执行代码

JS 执行代码的过程

  • 执行全局代码时,创建全局上下文
  • 调用函数时,创建函数上下文
  • 使用 eval 函数时,创建 eval 上下文
  • 执行局部代码时,创建局部上下文

关于 Babel

Babel ,又名 Babel.js。 是一个用于 web 开发,且自由开源的 JavaScript 编译器、转译器。

Babel 的编译流程:

图片来源:透過製作 Babel-plugin 初訪 AST

Parse

Babel 的第一步就是将源码转换为抽象语法树(AST)

const babel = require('@babel/core');
const {
    parseAsync } = babel;
const parseCode = async (code = '', options = {
   }) => {
   
		const res = await parseAsync(code, options);
};
parseCode(`
		const a = 1;
`)

可通过 https://astexplorer.net/ 在线查看具体结果

这一步会将收集到的的代码,通过 词法分析(Lexical analysis)语法分析(Parsing) 两个阶段将代码转换成 AST

词法分析(Lexical analysis)

词法分析会将代码转为 token ,可以理解为是对每个不可分割单词元的描述,例如 const 就会转换成下面这样:

Token {
   
    type: 
        TokenType {
   
        label: 'const',
        keyword: 'const',
        beforeExpr: false,
        startsExpr: false,
        rightAssociative: false,
        isLoop: false,
        isAssign: false,
        prefix: false,
        postfix: false,
        binop: null,
        updateContext: null
    },
    value: 'const',
    start: 5,
    end: 10,
    loc: 
    SourceLocation {
   
        start: Position {
    line: 2, column: 4 },
        end: Position {
    line: 2, column: 9 },
        filename: undefined,
        identifierName: undefined
    }
}

type 就是 对 token 的描述,如果想要查看 bebal 生成的 token,我们可以在 options 里写入:

parserOpts: {
   
		tokens: true
}

关于 @babel/parser 更多配置,可查看:https://babeljs.io/docs/en/babel-parser#options

语法分析(Parsing)

语法分析则是将上述的 token 转换成对应的 ast 结构

所以我们就可以看到这样的一段树状结构(过滤部分信息)

{
   
    "type": "VariableDeclaration",
    "start": 0,
    "end": 14,
    "loc": {
   
        "start": {
   
            "line": 1,
            "column": 0
        },
        "end": {
   
            "line": 1,
            "column": 14
        }
    },
    "declarations": [
        {
   
            "type": "VariableDeclarator",
            "start": 6,
            "end": 13,
            "loc": {
   
                "start": {
   
                    "line": 1,
                    "column": 6
                },
                "end": {
   
            
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值