Babel是一個(gè)js編譯器,是一個(gè)源代碼到源代碼的轉(zhuǎn)換郊艘。Babel可以讓我們?cè)趈s新規(guī)范和特性全面普及之前就可以使用它們荷科。Babel的編譯分為語法和API兩部分:
· 語法,諸如const let ...解構(gòu)纱注、class語法等畏浆;
· API,諸如[].includes狞贱、[].reduce等
默認(rèn)的Babel如下刻获,只會(huì)編譯語法,不會(huì)編譯API:
{
"presets": [["@babel/preset-env"]]
}
Babel提供了polyfill庫進(jìn)行api的轉(zhuǎn)換瞎嬉,同時(shí) @babel/preset-env 提供了配置參數(shù) useBuiltIns 進(jìn)行設(shè)置如何處理蝎毡。
{
"presets": [[
"@babel/preset-env",
{
// ① 默認(rèn)值 false 不進(jìn)行api的轉(zhuǎn)換
// ② entry:需要在源代碼頂部手動(dòng)引入 @babel/polyfill ,但這樣所有的polyfill庫都會(huì)引入佑颇,增大打包體積
// ③ usage:按需引入顶掉,源代碼不必手動(dòng)引入polyfill草娜,減少打包體積挑胸,常見用法
"useBuiltIns": false | entry | usage
}
]]
}
但是polyfill的引入還有種常見做法是,源代碼處引入特定需要的polyfill庫(如@babel/polyfill-xx宰闰,沒用過)
上面的配置存在的問題:
- polyfill的轉(zhuǎn)換是通過直接global.Array.includes 或者 Array.prototype.includes 來實(shí)現(xiàn)的茬贵,這種做法直接修改全局變量及其原型簿透,造成原型污染或者不可預(yù)測(cè)的問題;
- babel對(duì)語法的轉(zhuǎn)換解藻,有時(shí)是通過一些稱為helpers的輔助函數(shù)實(shí)現(xiàn)的老充,babel會(huì)在需要轉(zhuǎn)換的地方把這些helpers函數(shù)都引入進(jìn)來,造成代碼重復(fù)螟左,打包體積變大啡浊。
@babel/plugin-transform-runtime 這個(gè)插件解決了上面的問題,它需要配合@babel/runtime-corejs3使用胶背。前者是轉(zhuǎn)換代碼巷嚣,轉(zhuǎn)換的代碼會(huì)將后者的模塊進(jìn)行引入,所以前者運(yùn)行在編譯時(shí)钳吟,后者運(yùn)行在運(yùn)行時(shí)廷粒。這樣helpers輔助函數(shù)和polyfill方法都從統(tǒng)一的 @babel/runtime-corejs3 引入,解決了上面的問題红且。
{
"presets": [[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
]],
"plugin": [[
"@babel/plugin-transform-runtime",
{
"corejs": 3
}
]]
}