昨天談完 TypeScript,了解到因為瀏覽器不支援 TypeScript,所以需要一個編譯器來轉換。
於是今天我們來談談另一個編譯器,扮演的角色比 TypeScript 更加舉足輕重 - Babel
隨著 ECMAScript 不斷更新版本,從 ES6 到 ES11,開發者不斷推出更易讀、好用的語法。
然而 ECMAScript 只是「規範」,從草案到定案,再到瀏覽器完成「實作」,中間的過程實在太久。
也就是說,知道有新語法,卻要等好一陣子才能使用,更何況即便瀏覽器好不容易支援新語法了,也要使用者有更新才行,如果要支援老舊瀏覽器,不就沒辦法了嗎?
Babel 是一個 JavaScript 編譯器,專門用來將 ECMAScript 2015 以上(即 ES6 以上) 的程式碼,轉成可以向下相容的版本,讓較舊的瀏覽器也能夠解讀:
Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.
整體來說有三個步驟:
其中最神秘的這個 AST(Abstract Syntax Tree),抽象語法樹,可以用這個網站來玩玩看,在左邊輸入一般的程式碼,就可以在右邊看到解析成 AST 的樣子。
比如輸入
console.log('hello world');
它的 AST 就會是:
{
"type": "Program",
"start": 0,
"end": 27,
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 27,
"expression": {
"type": "CallExpression",
"start": 0,
"end": 26,
"callee": {
"type": "MemberExpression",
"start": 0,
"end": 11,
"object": {
"type": "Identifier",
"start": 0,
"end": 7,
"name": "console"
},
"property": {
"type": "Identifier",
"start": 8,
"end": 11,
"name": "log"
},
"computed": false,
"optional": false
},
"arguments": [
{
"type": "Literal",
"start": 12,
"end": 25,
"value": "hello world",
"raw": "'hello world'"
}
],
"optional": false
}
}
],
"sourceType": "module"
}
(汗顏
看不懂也沒關係,但看一下關鍵字可以大概猜一下:
console
跟 log
)hello world
)也就是說,AST 比較像是,用樹狀的結構來表示這行程式碼在做什麼事。有了這個樹狀結構(其實就是個 JSON),各個 plugin 就可以各自處理對應的程式碼,轉換成瀏覽器可以讀懂的樣子。
babel 除了支援 ES6 外,也有支援 JSX 與 TypeScript,而這些都是透過 plugins 與 presets (preset 其實就是一組的 plugins):
甚至,你也可以自己寫一個 plugin 來轉換程式碼,AST 的原理是互通的,只要你寫的 plugin 可以讀取 AST,並轉換成相對應的格式,完全是可以的。
背後原理難度高,要搞懂 AST 很難,要自己寫 plugin 更難,不過如果只是要使用基本的功能,倒是不用擔心
基本上 Babel 可以說是標配了,但不是因為大家說他標配就是標配,而是因為如開頭說到的,ECMAScript 規範走在前面,而瀏覽器實作往往需要一段時間,而且使用者的瀏覽器版本不是我們可以控制的,在這個前提下,Babel 幾乎是必需品。
如果是純 ES5 以下的 JavaScript code,其實是不需要 Babel 的。(但這應該都是舊專案了)
Babel 真的堪稱是最默默做事的一個工具,因為我以前都用 ES5 以下的寫法,長大之後(?)跳到 React 框架,CRA 跟 Webpack 都幫我處理妥妥的,導致我根本不知道 Babel 到底做了什麼XD
今天研究之後才發現,Babel 背後的原理真的有夠難,看到那個 AST 差點暈倒,不過這也是這種 compiler 工具非常有價值的地方,正是因為一般人處理不來,所以將背後邏輯封裝成黑箱,裡面在做什麼不清楚,但我只要程式碼丟進去,出來就是所有瀏覽器暢通無阻。
必須感謝這些前人的努力啊~