@babel/preset-env和@babel/plugin-transform-runtime傻傻分不清

前言

babel只是轉(zhuǎn)換語法,后為了解決API的兼容掘托,又引入了pollify概念瘦锹,再后來為了解決組件開發(fā)者的環(huán)境多樣性,又引入了runtime闪盔。

本文以async弯院、Promise、Array.prototype.includes三個(gè)方法如何運(yùn)行在IE9中作為例子泪掀,粗略探討兩者之間的差別和使用听绳。
詳見官網(wǎng)

環(huán)境

為了清晰直觀,本文采用兩種方式編譯

  • @babel/cli
    直接編譯代碼异赫,更清晰看到babel幫我們引入了什么
  • rollup
    將代碼編譯成瀏覽器可運(yùn)行代碼椅挣,驗(yàn)證結(jié)果
  //package.json
  "devDependencies": {
    "@babel/cli": "^7.18.10",
    "@babel/core": "^7.18.10",
    "@babel/plugin-transform-runtime": "^7.18.10",
    "@babel/preset-env": "^7.18.10",
    "rollup": "^2.6.1",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-node-resolve": "^5.2.0"
  },
  "dependencies": {
    "@babel/runtime": "^7.18.9",
    "@babel/runtime-corejs3": "^7.18.9",
    "core-js": "^2.6.12"
  }
//rollup.config.js
import resolve from 'rollup-plugin-node-resolve';   //幫助rollup查找外部模塊,然后導(dǎo)入
import babel from 'rollup-plugin-babel';            
import commonjs from 'rollup-plugin-commonjs';      //將CommonJS模塊轉(zhuǎn)換為ES2015供rollup處理

export default {
    input: './a.js',
    output: {
        file: './b.js',
        format: 'iife'
    },
    plugins: [
        resolve(),
        babel({
            exclude: 'node_modules/**',
            runtimeHelpers: true      //啟用babel runtime
        }),
        commonjs({})
    ]
};

preset-env

說明

preset-env本身只解決了語法層面的問題祝辣,配合polyfill(polyfill是一個(gè)統(tǒng)稱贴妻,常見的包括@babel/polyfill和core-js等)可以解決api兼容問題
@babel/core 7.4.0后polyfill被廢棄,被core-js/stable代替(因?yàn)锧babel/polyfill的核心就是core-js)
來自官方:

As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features)

特別注意
如果要轉(zhuǎn)換generator或者async蝙斜,當(dāng)@babel/core版本小于7.18.0時(shí)名惩,需要自行加載regenerator-runtime
來自官方:

If you are compiling generators or async function to ES5, and you are using a version of @babel/core or @babel/plugin-transform-regenerator older than 7.18.0, you must also load the regenerator runtime package. It is automatically loaded when using @babel/preset-env's useBuiltIns: "usage" option or @babel/plugin-transform-runtime

配置

useBuiltIns

有三個(gè)值可選

false

不需要導(dǎo)入core-js
不用polyfill,如果入口文件中導(dǎo)入了core-js, 會(huì)無視targets的配置加載所有的 polyfill

entry

需要在入口文件中導(dǎo)入core-js

// a.js
import "core-js/stable";

(async () => {
    const arr = await Promise.resolve([1,2,3]);
    console.log(arr.includes(2));
})();
// .babelrc
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "debug": true,
                "useBuiltIns": "entry",
                // "corejs": {      //默認(rèn)version為2孕荠,使用3需要安裝core-js@3
                //     "version": "3"
                // },
                "targets":{
                    "browsers":["ie >= 9"]
                }
            }
        ]
    ]
}
直接編譯娩鹉,執(zhí)行命令:
npx babel a.js -o b.js

b.js結(jié)果如下:

image.png

可以看到babel導(dǎo)入了基于targets配置所有不支持的全部特性攻谁,并且注入了helper函數(shù)

rollup編譯,執(zhí)行命令:
npm run build

Edge中模擬IE9順利打印出true

usage

需要在入口文件中導(dǎo)入core-js(a.js同上)

// .babelrc
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "debug": true,
                "useBuiltIns": "usage",
                // "corejs": {      //默認(rèn)version為2弯予,使用3需要安裝core-js@3
                //     "version": "3"
                // },
                "targets":{
                    "browsers":["ie >= 9"]
                }
            }
        ]
    ]
}
直接編譯戚宦,執(zhí)行命令:
npx babel a.js -o b.js

b.js結(jié)果如下:


image.png

可以看到babel只導(dǎo)入了基于targets配置且在代碼中使用到的特性,并且注入了helper函數(shù)

rollup編譯锈嫩,執(zhí)行命令:
npm run build

Edge中模擬IE9順利打印出true

plugin-transform-runtime

說明

plugin-transform-runtime配和runtime使用可以按需引入特性受楼,并且掛載在內(nèi)建變量中,不污染全局呼寸,特別適合組件開發(fā)者使用艳汽。

runtime

組成

runtime包含了helper 的 runtime 版本,corejs对雪,和實(shí)現(xiàn) async河狐、await 的regenerator
runtime 這3部分除了 helper 其他都是第三方的

作用

  • 自動(dòng)移除語法轉(zhuǎn)換后內(nèi)聯(lián)的輔助函數(shù)(inline Babel helpers),使用@babel/runtime/helpers里的輔助函數(shù)來替代瑟捣;

  • 當(dāng)代碼里使用了core-js的API馋艺,自動(dòng)引入@babel/runtime-corejs3/core-js-stable/,以此來替代全局引入的core-js/stable;

  • 當(dāng)代碼里使用了generator/async函數(shù)迈套,自動(dòng)引入@babel/runtime/regenerator捐祠,以此來替代全局引入的regenerator-runtime/runtime;

到這兒你應(yīng)該知道了交汤,plugin-transform-runtime其實(shí)是preset-env的增強(qiáng)

特別注意
corejs2僅支持全局變量和靜態(tài)屬性polyfill(例如:Promise和Array.from)雏赦,要兼容incluedes等實(shí)例屬性需要用到corejs3

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

配置

corejs

不需要導(dǎo)入core-js

// a.js
(async () => {
    const arr = await Promise.resolve([1,2,3]);
    console.log(arr.includes(2));
})();
// .babelrc
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "debug": true,
                "targets":{
                    "browsers":["ie >= 9"]
                }
            }
        ]
    ],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            {
                "corejs": "3"
            }
        ]
    ]
}
直接編譯,執(zhí)行命令:
npx babel a.js -o b.js

b.js結(jié)果如下:


image.png

可以看到內(nèi)聯(lián)的helper函數(shù)都被@babel/runtime-corejs3/helpers/替換芙扎,并且只導(dǎo)入了基于targets配置且在代碼中使用到的特性

rollup編譯,執(zhí)行命令:
npm run build

Edge中模擬IE9順利打印出true

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末填大,一起剝皮案震驚了整個(gè)濱河市戒洼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌允华,老刑警劉巖圈浇,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異靴寂,居然都是意外死亡磷蜀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門百炬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來褐隆,“玉大人,你說我怎么就攤上這事剖踊∈” “怎么了衫贬?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長歇攻。 經(jīng)常有香客問我固惯,道長,這世上最難降的妖魔是什么缴守? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任葬毫,我火速辦了婚禮,結(jié)果婚禮上屡穗,老公的妹妹穿的比我還像新娘贴捡。我一直安慰自己,他們只是感情好鸡捐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布栈暇。 她就那樣靜靜地躺著,像睡著了一般箍镜。 火紅的嫁衣襯著肌膚如雪源祈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天色迂,我揣著相機(jī)與錄音香缺,去河邊找鬼。 笑死歇僧,一個(gè)胖子當(dāng)著我的面吹牛图张,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诈悍,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼祸轮,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了侥钳?” 一聲冷哼從身側(cè)響起适袜,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舷夺,沒想到半個(gè)月后苦酱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡给猾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年疫萤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敢伸。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扯饶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情帝际,我是刑警寧澤蔓同,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蹲诀,受9級(jí)特大地震影響斑粱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脯爪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一则北、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧痕慢,春花似錦尚揣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至塔次,卻和暖如春方篮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背励负。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工藕溅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人继榆。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓巾表,卻偏偏與公主長得像,于是被迫代替她去往敵國和親略吨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子集币,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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