[深刻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
[react] Hooksjavascript
[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CIhtml
[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程前端
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 对象文档vue
abstract syntax tree:抽象语法树
abstract:抽象的java
源码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.im/post/5dca1e…
AST 从babel讲到AST juejin.im/post/5ab35c…
AST 99%的人不了解的AST segmentfault.com/a/119000001…
AST 抽象语法树-图形 juejin.im/post/5bff94…
AST 具体细节:segmentfault.com/a/119000001…
AST cheogo.github.io/learn-javas…
AST详细 www.codercto.com/a/88752.htm…node
babel转换 juejin.im/post/5dca1e…
babel转换案例 cloud.tencent.com/developer/a…
babel插件介绍 zhuanlan.zhihu.com/p/61780633react