[深刻01] 执行上下文
[深刻02] 原型链
[深刻03] 继承
[深刻04] 事件循环
[深刻05] 柯里化 偏函数 函数记忆
[深刻06] 隐式转换 和 运算符
[深刻07] 浏览器缓存机制(http缓存机制)
[深刻08] 前端安全
[深刻09] 深浅拷贝
[深刻10] Debounce Throttle
[深刻11] 前端路由
[深刻12] 前端模块化
[深刻13] 观察者模式 发布订阅模式 双向数据绑定
[深刻14] canvas
[深刻15] webSocket
[深刻16] webpack
[深刻17] http 和 https
[深刻18] CSS-interview
[深刻19] 手写Promise
[深刻20] 手写函数javascript
[react] Hookshtml
[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI前端
[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程
[源码-vue03] watch 侦听属性 - 初始化和更新
[源码-vue04] Vue.set 和 vm.$set
[源码-vue05] Vue.extend vue
[源码-vue06] Vue.nextTick 和 vm.$nextTick java
abstract:抽象的 ( abstract syntax tree:抽象语法树 ) Identifier:标识符 Punctuator :标点符号 declaration:声明 VariableDeclaration:变量声明 declarator:声明人 traverse:遍历 expression:表达,表达式 performance:性能 // while parseExpression() tries to parse a single Expression with performance in mind. // 而parseExpression()会尝试在考虑性能的状况下解析单个Expression doubt:疑惑 // When in doubt, use .parse() // 若是有疑惑的状况,请使用.parse()而不要使用.parseExpression() Numeric:数字 复制代码
AST explorer 查看源码对应的AST和JSON结构
esprima 能够查看词法分词阶段生成的tokens
AST 可视化工具 查看AST可视化树状图
AST 对象文档node
abstract syntax tree:抽象语法树
abstract:抽象的react
源码1: const add = (a, b) => { return a + b } tokens: [ { "type": "Keyword", "value": "const" }, { "type": "Identifier", "value": "add" }, { "type": "Punctuator", "value": "=" }, { "type": "Punctuator", "value": "(" }, { "type": "Identifier", "value": "a" }, { "type": "Punctuator", "value": "," }, { "type": "Identifier", "value": "b" }, { "type": "Punctuator", "value": ")" }, { "type": "Punctuator", "value": "=>" }, { "type": "Punctuator", "value": "{" }, { "type": "Keyword", "value": "return" }, { "type": "Identifier", "value": "a" }, { "type": "Punctuator", "value": "+" }, { "type": "Identifier", "value": "b" }, { "type": "Punctuator", "value": "}" } ] --- 源码2: const a = 1; tokens: [ { "type": "Keyword","value": "const" }, { "type": "Identifier","value": "a" }, { "type": "Punctuator","value": "=" }, { "type": "Numeric","value": "1" }, { "type": "Punctuator","value": ";" } ] 说明: (1) tokens是具备type,value属性的对象组成的数组 (2) token是词法分析的最小单元,不能再分解 (3) 常见的type - keyword关键字 - identfier标识符 - punctuator标点符号 - Numeric:数字 复制代码
源码: var a = 1; AST { "type": "Program", "start": 0, "end": 12, "body": [ // ---------------------------------------------- body表示代码具体的内容 { // ---------------------------------------------------- statement内容块对象,一个body可能包含多个statement "type": "VariableDeclaration", // --------------------- 变量声明 "start": 0, "end": 10, "declarations": [ { "type": "VariableDeclarator", // ------------------ 变量声明 "start": 4, "end": 9, "id": { "type": "Identifier", // ------------------------- 标识符 "start": 4, "end": 5, "name": "a" }, "init": { "type": "Literal", "start": 8, "end": 9, "value": 1, "raw": "1" } } ], "kind": "var" // --------------------------------------- 变量类型 } ], "sourceType": "module" } 说明: (1) 最外层属性:type,start,end,body[],sourceType - body:表示代码的具体内容 - 内容块:body中可能包含多个内容块,每一个内容块用一个对象表示 - 内容块包含: - type - start - end - kind - declarations:乘装变量内容的块,这个块也是一个数组,由于变量声明可能生命多个 - type - start - end - id - type - start - end - name - sourceType:表示语言的种类 (2) body是一个数组,成员是statement内容块对象,由于body能够包含多个statement内容块 - statement 有不少类型,好比说变量声明,函数定义,if语句,while循环,等都是一个statement - VariableDeclaration:变量声明 - FunctionDeclaration:函数定义 - IfStatement:if语句 - WhileStatement:while循环 复制代码
babelParser.parse(code, [options]) ------------------------------------ 解析全部代码 babelParser.parseExpression(code, [options]) -------------------------- 解析单个表达式 参数: - code:表示源码字符串 - options:配置对象,可选 - allowImportExportEverywhere:默认import和export声明只能出如今顶部,当此选项为true则能够出如今任何地方 - ... 复制代码
import * as babylon from "babylon"; import traverse from "babel-traverse"; // 源码string const code = `function square(n) { return n * n; }`; // 解析 parse:string -> ast const ast = babylon.parse(code); // 转换 transform:ast -> modified ast traverse(ast, { enter(path) { if ( path.node.type === "Identifier" && path.node.name === "n" ) { path.node.name = "x"; // ---------------- 若是是标识符而且标识符的名字是n,就把n改成x } } 复制代码
import {parse} from '@babel/parser'; import generate from '@babel/generator'; const code = 'class Example {}'; const ast = parse(code); const output = generate(ast, { /* options */ }, code); 复制代码
// 输入
const numberFive = 5;
// 输出
const NUMBERFIVE = 5;
复制代码
安装
@babel/core ----------------------- babel核心模块
@babel/parser --------------------- 字符流 -> token流 -> AST
@babel/traverse ------------------- AST -> modified AST
@babel/generator ------------------ modified AST -> 字符流
npm install @babel/core @babel/parser @babel/traverse @babel/generator -S
复制代码
代码 const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const generator = require('@babel/generator').default; // 源码字符串 const code = ` const nubmerFive = 5 `; // 解析 let AST = parser.parse(code) // 转换 traverse(AST, { enter(path) { console.log(path.node.type, 'path.node.type') if (path.node.type === 'Identifier') { // 若是node类型是标识符,就将name转成大写形式 path.node.name = path.node.name.toUpperCase() } } }) // 生成 const outputObj = generator(AST) const outputStr = outputObj.code; console.log(outputStr, 'outputStr') 复制代码
AST babel-AST相关工具 juejin.cn/post/684490…
AST 从babel讲到AST juejin.cn/post/684490…
AST 99%的人不了解的AST segmentfault.com/a/119000001…
AST 抽象语法树-图形 juejin.cn/post/684490…
AST 具体细节:segmentfault.com/a/119000001…
AST cheogo.github.io/learn-javas…
AST详细 www.codercto.com/a/88752.htm…webpack
babel转换 juejin.cn/post/684490…
babel转换案例 cloud.tencent.com/developer/a…
babel插件介绍 zhuanlan.zhihu.com/p/61780633ios