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

說實話,真看不懂呀!

Tags: