babel 本質上是個編譯器,因此它所作的基本上就是編譯器要作的事,爲了不對編譯器的某些東西講的太細,咱們重點只要知道 babel 的工做流程就好了。javascript
第一步能夠說是是編譯器的基本功能,經過解析器將原始代碼轉換成抽象語法樹(AST),顧名思義就是描述語法的數據結構,通常在這一步編譯器都會作兩件事:語法分析與語義分析。語法分析是去定義原始代碼中的內容是否應該被認爲一個單位,而後是語義分析,判斷這些單位組合而成的是否爲語法,例如用於 for 循環等,在這一步中實際上插件幾乎什麼也作不了,由於 babel 並不支持改變解析的流程css
但 babel 有幾個內建的解析插件,這部份能夠由plugin去開關,不過這通常也會經過官方的plugin去開關這些功能,主要是確保不會直接使用到babel內部的選項,這就是babel官方插件的名字中帶有syntax
的插件在作的事。前端
這裏要介紹一個工具:AST Explorer,它可讓你能夠看到各類語言的 AST 語法樹,也能夠在這上面測試 babel 插件,這對要寫 babel 插件的人來講很是方便,後面會用這個工具來幫咱們寫一個 babel 插件。先來一個例子:java
function answer() { return 'The answer to life, the universe and everything' }
轉成 AST 後大概就是這樣,這裏用 json 表示並省略了位置等信息:node
{ "type": "File", "program": { "type": "Program", "body": [ { "type": "FunctionDeclaration", "id": { "type": "Identifier", "name": "answer" }, "body": { "type": "BlockStatement", "body": [ { "type": "ReturnStatement", "argument": { "type": "StringLiteral", "value": "The answer to life, the universe and everything" } } ] } } ] } }
補充:ASTExplorer 支持不少程序語言,js、css、go、python 等,有興趣能夠玩玩。
babel 會按順序訪問每一個 AST 上的節點,並調用插件對應的函數,這一步纔是插件要作的,在遍歷時 babel 會爲每一個節點創建一個名爲 Path 的對象,這個對象會包含這個節點的信息,也可讓你訪問它的父節點或子節點,同時在這個對象上也會有各類方法讓你來修改節點的內容與結構,從而替換掉一個結點:python
export default function (babel) { const { types: t } = babel; return { visitor: { StringLiteral(path) { // 若是遇到一個字符串常數 // 常數的內容是指定的字符串 if (path.node.value === 'The answer to life, the universe and everything') { path.replaceWith(t.numericLiteral(42)) // 換成數字的 42 } } } }; }
上面的代碼就能夠用 AST Explorer 試試了,點擊 AST Explorer 上面的 Transform
的菜單,選擇 babelv7 後,下面就會多一個編輯器讓你輸入,上面的代碼就能夠直接使用了程序員
最後 babel 會把修改過的 AST 再轉回代碼。面試
function answer() { return 42; }
剩下的工做就是寫入文件,或者再進一步處理。其實轉換回代碼後 babel 的工做就結束了。json