關(guān)于 BABEL

什么是 BABEL

Babel 官方文檔: https://babeljs.io/

我們知道各個瀏覽器對 JavaScript 版本的支持各不相同糊啡,有很多優(yōu)秀的新語法都不能直接在瀏覽器中運行梭依。為了解決這個“溝通不暢”的問題,所以就有了 Babel,Babel 的出現(xiàn)使得我們可以無須顧忌的去使用 ES6+ 的語法姜性。

Babel is a JavaScript compiler.

這也是為何我們必須使用 ES6+ 語法的前提條件儡炼。

BABEL 如何編譯

先看下面這張圖:

你會發(fā)現(xiàn) ES6 的語法確實被編譯成瀏覽器可以識別的版本了楣责,你是不是也在問這是怎么做到的呢?

BABEL 編譯的階段

babel 總共分為三個階段:解析驻龟,轉(zhuǎn)換缸匪,生成翁狐。

我們需要知道現(xiàn)在 babel 本身是不具備這種轉(zhuǎn)化功能,提供這些轉(zhuǎn)化功能的是一個個 plugin凌蔬。所以我們沒有配置任何 plugin 的時候露懒,經(jīng)過 Babel 輸出的代碼是沒有改變的。

640?wx_fmt=png

PLUGIN —— TRANSFORM 的載體

Babel 自 6.0 起砂心,就不再對代碼進行轉(zhuǎn)換⌒复剩現(xiàn)在只負責(zé)圖中的 parse 和 generate 流程,轉(zhuǎn)換代碼的 transform 過程全都交給插件去做辩诞。

例子:

// 模板字面量    
const name = '小生方勤';    
let hello = `hello ${name}`;

上面是一個簡單的模板字面量的例子坎弯,我們清楚這個是 ES6 的新特性,在不支持 ES6 的運行平臺這段代碼是會報錯的躁倒,所以我們需要 Babel 來將其編譯成 ES5 的代碼荞怒。

所以我們需要如下來配置 babel:

// .babelrc 文件  
{   
  "plugins": [  
    "transform-es2015-template-literals"  // 轉(zhuǎn)譯模版字符串的 plugins   
  ],    
  "presets": ["env", "stage-2"] 
}

preset(即一組預(yù)先設(shè)定的插件)

preset: babel 插件集合的預(yù)設(shè),包含某些插件 plugin秧秉。顯然像上面那樣一個一個配置插件會非常的麻煩褐桌,為了方便,babel 為我們提供了一個配置項叫做 persets(預(yù)設(shè))象迎。

當(dāng)前 babel 推薦使用 babel-preset-env 替代 babel-preset-es201X ,env 的支持范圍更廣荧嵌,包含es201X 的所有語法編譯,并且它可以根據(jù)項目運行平臺的支持情況自行選擇編譯版本砾淌。

PLUGINS 與 PRESETS 同時存在的執(zhí)行順序

  1. 先執(zhí)行 plugins 的配置項,再執(zhí)行 Preset 的配置項啦撮;

  2. plugins 配置項,按照聲明順序執(zhí)行汪厨;

  3. Preset 配置項赃春,按照聲明逆序執(zhí)行。

列入以下代碼的執(zhí)行順序為:

  1. transform-es2015-template-literals

  2. stage-2

  3. env

// .babelrc 文件  
{   
    "plugins": [    
        "transform-es2015-template-literals",  // 轉(zhuǎn)譯模版字符串的 plugins  
    ],  
    "presets": [    
        ["env", {   
            // 是否自動引入 polyfill劫乱,開啟此選項必須保證已經(jīng)安裝了 babel-polyfill    
            // “usage” | “entry” | false, defaults to false.    
            "useBuiltIns": "usage"  
        }], "stage-2"]  
}

這里講一講 useBuiltIns 配置

我們可能在全局引入 babel-polyfill织中,這樣打包后的整個文件體積必然是會變大的。

但是通過設(shè)置 "useBuiltIns":"usage" 能夠把 babel-polyfill 中你需要用到的部分提取出來衷戈,不需要的去除狭吼。

useBuiltIns 參數(shù)說明:

  1. false: 不對 polyfills 做任何操作

  2. entry: 根據(jù) target 中瀏覽器版本的支持,將 polyfills 拆分引入殖妇,僅引入有瀏覽器不支持的 polyfill

  3. usage(新):檢測代碼中 ES6/7/8 等的使用情況刁笙,僅僅加載代碼中用到的 polyfills

BABEL 相關(guān)模塊簡要說明

了解過 Babel 的同學(xué),是否也覺得的模塊有點多呢?我開始學(xué)習(xí)的時候就有這種感覺疲吸。其實每個模塊是各司其職的座每。

BABEL-CORE(核心)

這個模塊是最能顧名思義的了,即 babel 的核心模塊摘悴。babel 的核心 api 都在這個模塊中尺栖。也就是這個模塊會把我們寫的 js 代碼抽象成 AST 樹;然后再將 plugins 轉(zhuǎn)譯好的內(nèi)容解析為 js 代碼烦租。

具體怎么工作的這里就不詳細說了,因為我也不知道除盏。

BABEL-CLI

babel-cli 官方文檔:https://babeljs.io/docs/en/babel-cli/

babel-cli 是一個通過命令行對 js 文件進行轉(zhuǎn)換的工具叉橱。

當(dāng)然我們一般不會使用到這個模塊,因為一般我們都不會手動去做這個工作者蠕,這個工作基本都集成到模塊化管理工具中去了窃祝,比如 webpack、Rollup 等踱侣。

簡單使用(需要先安裝 babel-cli):

babel test.js -o compiled.js

BABEL-NODE

babel-node 是 babel-cli 的一部分粪小,所以它在安裝 babel-cli 的時候也同時安裝了。

它使 ES6+ 可以直接運行在 node 環(huán)境中抡句。

BABEL-POLYFILL(內(nèi)部集成了 CORE-JS 和 REGENERATOR)

babel 對一些新的 API 是無法轉(zhuǎn)換探膊,比如 Generator、Set待榔、Proxy逞壁、Promise 等全局對象,以及新增的一些方法:includes锐锣、Array.form 等腌闯。所以這個時候就需要一些工具來為瀏覽器做這個兼容。

官網(wǎng)的定義:babel-polyfill 是為了模擬一個完整的 ES6+ 環(huán)境雕憔,旨在用于應(yīng)用程序而不是庫/工具姿骏。

babel-polyfill 主要有兩個缺點:

  1. 使用 babel-polyfill 會導(dǎo)致打出來的包非常大,很多其實沒有用到斤彼,對資源來說是一種浪費分瘦。

  2. babel-polyfill 可能會污染全局變量,給很多類的原型鏈上都作了修改畅卓,這就有不可控的因素存在擅腰。

因為上面兩個問題,所以在 Babel7 中增加了 babel-preset-env翁潘,我們設(shè)置 "useBuiltIns":"usage"這個參數(shù)值就可以實現(xiàn)按需加載 babel-polyfill 啦趁冈。

BABEL-RUNTIME & BABEL-PLUGIN-TRANSFORM-RUNTIME

在使用 Babel6 的時候, .babelrc 文件中會使用 babel-plugin-transform-runtime,而 package.json 中的 dependencies 同時包含了 babel-runtime渗勘,因為在使用 babel-plugin-transform-runtime 的時候必須把 babel-runtime 當(dāng)做依賴沐绒。

.babelrc 配置:

{   
  "presets": [  
    ["env"] 
  ],    
  "plugins": [  
    ["transform-runtime", { 
      "helpers": false, // defaults to true 
      "polyfill": false, // defaults to true    
      "regenerator": true, // defaults to true  
      "moduleName": "babel-runtime" // defaults to "babel-runtime"  
    }]  
  ] 
}

我們在啟用插件 babel-plugin-transform-runtime 后,Babel 就會使用 babel-runtime 下的工具函數(shù)旺坠,將一些瀏覽器不能支持的特性重寫乔遮,然后在項目中使用。

babel-runtime 內(nèi)部也集成了 core-js取刃、 regenerator蹋肮、helpers 等

由于采用了沙盒機制,這種做法不會污染全局變量璧疗,也不會去修改內(nèi)建類的原型坯辩,所以會有重復(fù)引用的問題。

現(xiàn)在最好的實踐應(yīng)該是在 babel-preset-env 設(shè)置 "useBuiltIns": "usage"崩侠,按需引入 polyfill漆魔。

三種方案對比

方案 優(yōu)點 缺點
@babel/runtime & @babel/plugin-transform-runtime 按需引入, 打包體積小 不能兼容實例方法
@babel/polyfill 完整模擬 ES2015+ 環(huán)境 打包體積過大, 污染全局對象和內(nèi)置的對象原型
@babel/preset-env 按需引入, 可配置性高 小生不知 -_-

BABEL7 的一些變化

PRESET 的變更:

淘汰 es201x,刪除 stage-x却音,推薦 env

如果你還在使用 es201x改抡,官方建議使用 env 進行替換。淘汰并不是刪除系瓢,只是不推薦使用阿纤。

但 stage-x 是直接被刪了,也就是說在 babel7 中使用 es201X 是會報錯的八拱。

包名稱變化

babel 7 的一個重大變化阵赠,把所有 babel-* 重命名為 @babel/*,

例如:

  1. babel-cli —> @babel/cli肌稻。

  2. babel-preset-env —> @babel/preset-env

低版本 NODE 不再支持

babel 7.0 開始不再支持 nodejs 0.10, 0.12, 4, 5 這四個版本清蚀,相當(dāng)于要求 nodejs >= 6爹耗。

還有一些包從其他包獨立出來的變化等等

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苔悦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抖部,更是在濱河造成了極大的恐慌诺凡,老刑警劉巖东揣,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腹泌,居然都是意外死亡嘶卧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門凉袱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芥吟,“玉大人侦铜,你說我怎么就攤上這事≈油遥” “怎么了钉稍?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棺耍。 經(jīng)常有香客問我贡未,道長,這世上最難降的妖魔是什么蒙袍? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任俊卤,我火速辦了婚禮,結(jié)果婚禮上害幅,老公的妹妹穿的比我還像新娘瘾蛋。我一直安慰自己,他們只是感情好矫限,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著佩抹,像睡著了一般叼风。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棍苹,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天无宿,我揣著相機與錄音,去河邊找鬼枢里。 笑死孽鸡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的栏豺。 我是一名探鬼主播彬碱,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼奥洼!你這毒婦竟也來了巷疼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤灵奖,失蹤者是張志新(化名)和其女友劉穎嚼沿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓷患,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡骡尽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了擅编。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攀细。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辨图,到底是詐尸還是另有隱情班套,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布故河,位于F島的核電站吱韭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鱼的。R本人自食惡果不足惜理盆,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凑阶。 院中可真熱鬧猿规,春花似錦、人聲如沸宙橱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽师郑。三九已至环葵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宝冕,已是汗流浹背张遭。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留地梨,地道東北人菊卷。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像宝剖,于是被迫代替她去往敵國和親洁闰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容