前言
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 includingcore-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 than7.18.0
, you must also load theregenerator runtime
package. It is automatically loaded when using@babel/preset-env
'suseBuiltIns: "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é)果如下:
可以看到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é)果如下:
可以看到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é)果如下:
可以看到內(nèi)聯(lián)的helper函數(shù)都被@babel/runtime-corejs3/helpers/替換芙扎,并且只導(dǎo)入了基于targets配置且在代碼中使用到的特性
rollup編譯,執(zhí)行命令:
npm run build
Edge中模擬IE9順利打印出true