babel 學(xué)習(xí)筆記

參考了很多文章庸娱,只是為了搞清楚babel 7 之后容易搞混的概念铃拇。

介紹

本文主要解決如下幾個問題:

  1. babel 是什么泰偿?
  2. babel 的原理是什么通危?
  3. babel 7 常見的核心包有哪些?
  4. babel 7 的最佳配置實(shí)踐

一灌曙、babel 是什么菊碟?

babel 是一個 JavaScript 編譯器。

除了常用的 將新語法轉(zhuǎn)換為向后兼容的語法外在刺,還支持如下功能:

  • 支持語法擴(kuò)展(例如 JSX)
  • 支持靜態(tài)類型檢查的流式語法

二逆害、babel 的原理是什么头镊?

babel 的 三個主要處理步驟分別是:解析(parse)轉(zhuǎn)換(transform)魄幕、生成(generate)相艇。

babel 處理步驟

2.1 解析

解析步驟接收代碼并輸出抽象語法樹(AST)。

  • 詞法分析
    詞法分析階段把字符串形式的代碼轉(zhuǎn)換為令牌(tokens)流纯陨。
  • 語法分析
    語法分析階段使用令牌中的信息把令牌流轉(zhuǎn)換成 AST 的形式坛芽。

2.2 轉(zhuǎn)換

轉(zhuǎn)換步驟接收 AST 并對其進(jìn)行遍歷,在此過程中對節(jié)點(diǎn)進(jìn)行添加翼抠、更新及移除等操作咙轩。

2.3 生成

代碼生成步驟把最終的 AST 轉(zhuǎn)換成字符串形式的代碼,同時還會創(chuàng)建源碼映射阴颖。

三活喊、babel 7 常見的核心包有哪些?

babel 7

3.1 @babel/preset-env

@babel/preset-env 是一個智能的 babel 預(yù)設(shè)量愧,讓你能使用最新的 JavaScript 語法钾菊,他會幫你轉(zhuǎn)換成代碼的目標(biāo)運(yùn)行環(huán)境支持的語法,提升你的開發(fā)效率并讓打包后的代碼體積更小偎肃。

運(yùn)行機(jī)制:
@babel/preset-env 依賴了許多優(yōu)秀的開源庫煞烫,并利用它們維護(hù)和增強(qiáng) Babel 語法轉(zhuǎn)換、語法實(shí)現(xiàn)软棺,來支持對于的目標(biāo)環(huán)境的版本的語法红竭、特征。

重要的配置項(xiàng):

target 可以指定瀏覽器類型喘落。
這里推薦使用單獨(dú)的文件 browserslistrc 來指定目標(biāo)瀏覽器茵宪,因?yàn)槌?babel 還有其他插件,例如 postcss 也會用到瘦棋。

useBuiltIns 配置@babel/preset-env 如何處理 polyfill

  • entry
    這個屬性將會把 import "@babel/polyfill 或者 require("@babel/polyfill") 替換成對應(yīng)環(huán)境(基于配置的目標(biāo)環(huán)境)的 polyfill稀火。
  • usage
    按需加載需要的polyfill, 一個打包的 bundle 之后加載一次。
  • false
    不加載polyfill

3.2 @babel/polyfill

@babel/polyfill模塊包括core-js 和一個自定義的 regenerator runtime 模塊用于模擬完整的 ES2015+ 環(huán)境赌朋。

  • 新的內(nèi)置組件:Promise凰狞、WeakMap
  • 靜態(tài)方法:Array.from、Object,assign()
  • 實(shí)例方法:Array.prototype.includes
  • 生成器函數(shù)

弊端:會污染全局

Babel 7.4 之后廢棄了 @babel/polyfill, 不再推薦使用沛慢。需要分別引入

import "core-js/stable";
import "regenerator-runtime/runtime";

3.3 @babel/plugin-transform-runtime

@babel/plugin-transform-runtime 是一個可重新使用Babel注入的幫助程序代碼以節(jié)省代碼大小的插件赡若。

諸如“ foobar” .includes(“ foo”)之類的實(shí)例方法僅適用于core-js @ 3。
如果您需要填充它們团甲,則可以直接導(dǎo)入“ core-js”或使用@babel/preset-env的useBuiltIns選項(xiàng)逾冬。

為什么需要 @babel/plugin-transform-runtime?

默認(rèn)情況下,輔助函數(shù)將被添加到需要它的每個文件中。有時不需要重復(fù)身腻,特別是當(dāng)您的應(yīng)用程序分布在多個文件中時产还。

  1. 所有輔助函數(shù)都將引用模塊@babel/runtime,以避免在編譯后的輸出中出現(xiàn)重復(fù)嘀趟。運(yùn)行時將被編譯到您的構(gòu)建中脐区。

  2. 該插件的另一個目的是為您的代碼創(chuàng)建一個沙盒環(huán)境。如果直接導(dǎo)入core-js或@babel/polyfill及其提供的內(nèi)置程序(例如Promise她按,Set和Map)牛隅,則這些將污染全局范圍。雖然這對于應(yīng)用程序或命令行工具可能是可以的尤溜,但是如果您的代碼是要發(fā)布供他人使用的庫倔叼,或者您無法完全控制代碼運(yùn)行的環(huán)境,則將成為一個問題宫莱。

corejs option Install command
false npm install --save @babel/runtime
2 npm install --save @babel/runtime-corejs2
3 npm install --save @babel/runtime-corejs3

四丈攒、區(qū)分開發(fā)依賴和生產(chǎn)依賴

Babel 7.4 版本

需要作為開發(fā)依賴的:
@babel/preset-env@babel/plugin-transform-runtime授霸、@babel/polyfill

需要作為生產(chǎn)依賴的:
@babel/runtime巡验、regenerator-runtimecore-js

總結(jié)

@babel/preset-env 是為了解決按需加載 polyfill
@babel/polyfill 是為了提供語法之外的墊片(內(nèi)置組件碘耳、靜態(tài)方法显设、實(shí)例方法等)
@babel/plugin-transform-runtime 是為了解決全局污染和輔助函數(shù)的重復(fù)引入

五、實(shí)踐

5.1 babel 的疑惑解答

說明一:@babel/preset-env 默認(rèn)配置辛辨,并不能完整的轉(zhuǎn)換 es6捕捂、以及 es7、es8 等新提案斗搞,它只能夠轉(zhuǎn)換新語法指攒,但是對于Array.includes() 、Promise 等并不支持

說明二:@babel/polyfill 提供了語法之外的墊片(內(nèi)置組件僻焚、靜態(tài)方法允悦、實(shí)例方法等),@babel/polyfill 依賴于 core-jsregenerator-runtime 實(shí)現(xiàn)的墊片

說明三: babel 7.4 之后廢棄了 @babel/polyfill 虑啤。

說明四:core-js 是 JavaScript 的模塊化標(biāo)準(zhǔn)庫隙弛,提供了大部分 ES2015+ 的 polyfill 。現(xiàn)在推薦使用 core-js@3狞山。

說明五:regenerator-runtime facebook 出品的一個提供編譯 generator全闷、async/await 的獨(dú)立運(yùn)行時。

總結(jié):babel 7.4 之后@babel/preset-env 需要和 core-js 萍启、regenerator-runtime 搭配使用总珠,才能提供完整的 ES2015+ 環(huán)境

5.2 普通應(yīng)用的 babel 配置

安裝babel 相關(guān)的依賴

yarn add @babel/core @babel/preset-env babel-loader --dev
yarn add core-js@3
yarn add regenerator-runtime

webpack.config.js

module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }

.babelrc 文件

{
  "presets": [
    [
      "@babel/preset-env", 
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
   ]
 }

說明一:babel-loader 是 webpack 的插件, 會默認(rèn)讀取 .babelrc中的配置
說明二:core-js@3regenerator-runtime 需要作為 dependencies, 因?yàn)檫@兩個依賴中的部分或全部代碼會被引入進(jìn)代碼,作為 polyfill,屬于生產(chǎn)依賴姚淆。
說明三:useBuiltIns 的參數(shù)選擇,推薦選擇 usage屡律,此選項(xiàng)將按需導(dǎo)入 polyfill腌逢。而 entry 會把全部的 polyfill 都引入到打包后的文件中。
說明四:useBuiltIns 會把 polyfill 引入到全局超埋,所以會污染全局搏讶。
說明五: useBuiltIns: usage 配置時,需要在主文件中主動引入 core-js

import "core-js/stable";
import "regenerator-runtime/runtime";

5.3 第三方庫的 babel 配置(待更新)

@babel/transform-runtime 會從 core-js-pure 這個包里去加載對應(yīng)的polyfill代碼霍殴,core-js-pure里面的代碼不會污染全局變量媒惕,適合第三方庫的開發(fā)。

-- 2020/01/07 更新 --

參考

babel 中文文檔-使用說明
Babel 手冊
劉小夕:不容錯過的 Babel7 知識
知乎:babel 只編譯語法
知乎:致我們學(xué)前端的小時光—corejs與env来庭、runtime的不解之緣
知乎:Babel學(xué)習(xí)系列4-polyfill和runtime差別(必看)
怎么給新手科普Babel:polyfill/preset-env/plugin-transform-runtime
關(guān)于Babel你只需要知道三個插件
一口(很長的)氣了解 babel
荒山:深入淺出 Babel 上篇:架構(gòu)和原理 + 實(shí)戰(zhàn)
倪曉磊:【工程化】@babel/preset-env 與@babel/plugin-transform-runtime 使用及場景區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末妒蔚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子月弛,更是在濱河造成了極大的恐慌肴盏,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帽衙,死亡現(xiàn)場離奇詭異菜皂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)厉萝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門恍飘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谴垫,你說我怎么就攤上這事章母。” “怎么了弹渔?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵胳施,是天一觀的道長。 經(jīng)常有香客問我肢专,道長舞肆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任博杖,我火速辦了婚禮椿胯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剃根。我一直安慰自己哩盲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著廉油,像睡著了一般惠险。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抒线,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天班巩,我揣著相機(jī)與錄音,去河邊找鬼嘶炭。 笑死抱慌,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的眨猎。 我是一名探鬼主播抑进,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼睡陪!你這毒婦竟也來了寺渗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宝穗,失蹤者是張志新(化名)和其女友劉穎户秤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逮矛,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸡号,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了须鼎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲸伴。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晋控,靈堂內(nèi)的尸體忽然破棺而出汞窗,到底是詐尸還是另有隱情,我是刑警寧澤赡译,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布仲吏,位于F島的核電站,受9級特大地震影響蝌焚,放射性物質(zhì)發(fā)生泄漏裹唆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一只洒、第九天 我趴在偏房一處隱蔽的房頂上張望许帐。 院中可真熱鬧,春花似錦毕谴、人聲如沸成畦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽循帐。三九已至框仔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拄养,已是汗流浹背存和。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衷旅,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓纵朋,卻偏偏與公主長得像柿顶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子操软,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

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