Babel 插件手冊 夢寐以求的文檔
- 2020 年 2 月 25 日
- 筆記
來源:https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md
Babel 的使用就是使用一些預設配置。預設就是一組插件,比如env, stage-3 flow react typescript預設。 Babel的核心就是插件,插件就是基於核心函數,對AST樹的一些操作 Babel 核心的核心就是一組函數 【重要函數】 parser traverse generator core.parser core.transorm 【輔助函數】 code-frame helpers template types Babel 插件手冊是官網編寫的插件指南!涉及基本概念,API,轉換操作,構建節點,最佳實踐等部分
一、基本概念
AST抽象語法樹
所有類型節點都有Node 介面以及其它參數,比如程式碼的起始位置,參數,左右節點等等:
interface Node { type: string; }Babel處理步驟
Babel 的三個主要處理步驟分別是: 解析(parse),轉換(transform),生成(generate)。.
遍歷AST之訪問者模式:
通過訪問者模式,訪問每一個節點! 深度遞歸遍歷整個樹。
1、訪問者名字:
最普通是用Node 的 type 名為訪問者的名字, 它是一個函數,但有幾種高級用法 ,見下面示例
const MyVisitor = { // 1、所有節點類型進入 參見:https://www.babeljs.cn/docs/babel-traverse#usage enter(path){} // 2、某類型的進入或退出 Identifier: { enter() { console.log("Entered!"); }, exit() { console.log("Exited!"); } } // 3、通過某個類型名稱 MemberExpression(){ } // 4、通過helps中定義 的 別名 Function(path) {} // 5、同時匹配幾種類型 "ExportNamedDeclaration|Flow"(path) {} }babel-types中已定義一組別名,比如Function 可以代表多種Node類型, FunctionDeclaration, FunctionExpression, ArrowFunctionExpression, ObjectMethod and ClassMethod 。參見下面源碼

2、訪問者的參數--path:
第一感覺,這個參數應該是Node,但通過前面程式碼可以發現它叫:path。
其實參數是Path對象,它是表示兩個節點之間連接的對象。 在巨大的AST樹中,用來表示節點的位置的對象,Path對象的node才是節點本身,parent是父節點對象。 還有其它很多相關屬性, 恩,想想也滿合理的設計,為插件編寫者省了不少力!
{ "parent": {...}, "node": {...}, "hub": {...}, "contexts": [], "data": {}, "shouldSkip": false, "shouldStop": false, "removed": false, "state": null, "opts": null, "skipKeys": null, "parentPath": null, "context": null, "container": null, "listKey": null, "inList": false, "parentKey": null, "key": null, "scope": null, "type": null, "typeAnnotation": null }3、執行訪問者:
traverse(someAST , MyVisitor )
每一個path對象也可以traverse. path.traverse( SomeVisitor , contextObj) 。此時就不傳入AST了,因為path已然包含AST資訊, 第二個參數contextObj是表示傳入SomeVisitor訪問都的上下文,可以通過this.xxxValue來訪問。
4、(訪問者間的)States
官方的例子看的人難受, 我以為它是想說明這樣一個問題:
所有的匹配到的訪問者函數會被調用,在函數中,不應該使用全局變數(也訪問者函數之外的變數),來維護某一個States。
如果我在某一個訪問函數中,計算出一個值,想把這個值傳遞給下級的AST樹,讓下級節點處理某一個操作時, 應該在當前位置執行一個新的traverse, 此即相當於嵌套遞歸。 前面的計算值可以通過對象contextObj 傳遞給下級AST樹 path.traverse( SomeVisitor , contextObj)
5、Scopes 和 Binding
說實話,真看不懂呀!
