[深刻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