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