babel
介紹
-
Babel
是一個(gè)JavaScript 編譯器
庶骄,可以把ES6
的語(yǔ)法轉(zhuǎn)為兼容瀏覽器的ES5
語(yǔ)法劫狠; -
Babel
可以單獨(dú)使用栅干,但是一般都是和webpack
結(jié)合一起使用 -
webpack
里使用babel
最基本的幾個(gè)包:babel-loader
新锈、babel-core
碍讨、babel-preset-env
治力、babel-polyfill
@babel/core
-
@babel/core
包括了整個(gè)babel
的工作流(輸入字符串 -> @babel/parser parser -> AST -> transformer[s] -> AST -> @babel/generator -> 輸出字符串
),是babel
的核心包勃黍。 - 可以看做
babel
的編譯器宵统。babel
的核心api
都在這里面,比如transform
覆获,主要都是處理轉(zhuǎn)碼的榜田。它會(huì)把我們的js
代碼,抽象成ast
锻梳,即abstract syntax tree
的縮寫(xiě)箭券,是源代碼的抽象語(yǔ)法結(jié)構(gòu)的樹(shù)狀表現(xiàn)形式。 - 我們可以理解為疑枯,它定義的一種分析
js
語(yǔ)法的樹(shù)狀結(jié)構(gòu)辩块。也就是說(shuō)es6
的新語(yǔ)法,跟老語(yǔ)法是不一樣的,那我們?cè)趺慈ザx這個(gè)語(yǔ)法呢废亭。所以必須要先轉(zhuǎn)成ast
国章,去發(fā)現(xiàn)這個(gè)語(yǔ)法的kind
,分別做對(duì)應(yīng)的處理豆村,才能轉(zhuǎn)化成es5
.
@babel/preset-env
-
Babel
插件一般盡可能拆成小的力度液兽,開(kāi)發(fā)者可以按需引進(jìn)。比如對(duì)ES6
轉(zhuǎn)ES5
的功能掌动,Babel
官方拆成了20+個(gè)插件四啰。 - 這樣的好處顯而易見(jiàn),既提高了性能粗恢,也提高了擴(kuò)展性柑晒。比如開(kāi)發(fā)者想要體驗(yàn)ES6的箭頭函數(shù)特性,那他只需要引入
transform-es2015-arrow-functions
插件就可以眷射,而不是加載ES6
全家桶匙赞。 - 但很多時(shí)候,逐個(gè)插件引入的效率比較低下妖碉。比如在項(xiàng)目開(kāi)發(fā)中涌庭,開(kāi)發(fā)者想要將所有ES6的代碼轉(zhuǎn)成
ES5
,插件逐個(gè)引入的方式令人抓狂欧宜,不單費(fèi)力坐榆,而且容易出錯(cuò)。 - 這個(gè)時(shí)候鱼鸠,可以采用
Babel Preset
猛拴。 - 可以簡(jiǎn)單的把
Babel Preset
視為Babel Plugin
的集合羹铅。 - 這個(gè)
preset
真是神器啊蚀狰,它能根據(jù)當(dāng)前的運(yùn)行環(huán)境,自動(dòng)確定你需要的plugins
和polyfills
职员。 -
Plugin
與Preset
執(zhí)行順序:可以同時(shí)使用多個(gè)Plugin
和Preset
麻蹋,此時(shí),它們的執(zhí)行順序非常重要焊切。先執(zhí)行完所有Plugin
扮授,再執(zhí)行Preset
。多個(gè)Plugin
专肪,按照聲明次序順序執(zhí)行刹勃。多個(gè)Preset
,按照聲明次序逆序執(zhí)行嚎尤。
browserslist
browserslist
指定了項(xiàng)目的目標(biāo)瀏覽器的范圍荔仁。這個(gè)值會(huì)被 @babel/preset-env
和 Autoprefixer
用來(lái)確定需要轉(zhuǎn)譯的 JavaScript
特性和需要添加的 CSS
瀏覽器前綴。
三種方式去配置:
- 在
.babelrc
或者babel.config.js
中去配置
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "4",
"chrome": "58",
"ie": "11"
}
}
]
]
}
- 在
package.json
里面增加如下配置
{
"browserslist": [
"last 1 version",
"> 1%",
"maintained node versions",
"not dead"
]
}
- 在工程的根目錄下存在
.browerslistrc
配置文件
last 1 version
> 1%
maintained node versions
not dead
除了browserslist
,另外還要在webpack.config.js
中配置babel-loader
module: {
rules: [
{ ...其他loader...},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
}
]
}
package.json
中也要配置相關(guān)的依賴(lài)
"dependencies": {
"babel-polyfill": "^6.26.0",
},
"devDependencies": {
"babel-core": "^6.22.1",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.3.2",
},
要用@babel/polyfill
的話(huà),還要在入口文件中引入
@babel/polyfill
&runtime
&core-js
-
Babel
默認(rèn)只轉(zhuǎn)換新的JavaScript
語(yǔ)法(syntax
)乏梁,如箭頭函數(shù)等次洼,而不轉(zhuǎn)換新的API
,比如Iterator遇骑、Generator卖毁、Set、Maps落萎、Proxy亥啦、Reflect、Symbol模暗、Promise
等全局對(duì)象禁悠,以及一些定義在全局對(duì)象上的方法(比如Object.assign
)都不會(huì)轉(zhuǎn)碼;所以光是使用@babel/preset-env
是不夠的兑宇,我們還需要polyfill
碍侦; -
@babel/polyfill
——讓目標(biāo)瀏覽器支持所有特性,不管它是全局的隶糕,還是原型的瓷产,或是其它。這樣枚驻,通過(guò)@babel/polyfill
濒旦,不同瀏覽器在特性支持上就站到同一起跑線(xiàn)。但是這樣做也有一個(gè)缺點(diǎn)再登,就是會(huì)污染全局變量尔邓,而且項(xiàng)目打包以后體積會(huì)增大很多,因?yàn)榘颜麄€(gè)依賴(lài)包也搭了進(jìn)去锉矢。所以并不推薦在一些方法類(lèi)庫(kù)中去使用梯嗽。 -
@babel/preset-env
下有一個(gè)選項(xiàng)useBuiltIns
,用于指導(dǎo)@babel/preset-env
如何觸發(fā)polyfills
.useBuiltIns
有三個(gè)可能的值usage | entry | false
沽损。usage:根據(jù)實(shí)際項(xiàng)目中真正使用到的有需要兼容的polyfill添加進(jìn)去 -
@babel/runtime
: -
@babel/runtime-corejs2
: