前言
问题
咱们在应用各种打包工具,须要配置 Babel
的时候,置信大家一开始都是间接在网上 复制粘贴 一段配置过去,而后能跑通就高枕无忧了吧?因而,咱们有时会遇到打包部署后,手机运行呈现白屏问题;或者是,打包后代码包过大,加载迟缓等等问题。
其实这所有,大部分起因是因为咱们对 Babel
各项配置没有一个零碎的了解,所以即便从网上复制粘贴了配置,呈现问题了,不晓得怎么去剖析呈现的问题。
筹备
如果你曾经对 Babel
曾经有一个大略的理解了,那浏览这篇文章,会让你对配置有一个更零碎的理解;如果你才刚接触 Babel
,或者对Babel
处于懵懵懂懂的状态,那我强烈建议你先浏览这篇文章——想弄懂 Babel?你必须得先弄清楚这几个包,它次要介绍剖析了一些概念跟以下几个包:
@babel/core
@bable/cli
@bable/preset-env
polyfill
@babel/polyfill
core-js
@babel/runtime
@babel/plugin-transform-runtime
并且为咱们答疑了一些看官网时的纳闷。因为在分明了这几包后,咱们学习配置这块会更容易了解一些。
备注
- 以后
@babel/core
最新版本是:7.20.12
- 以后
@babel/preset-env
最新版本是:7.20.2
再谈core-js
通过上篇文章—— 想弄懂 Babel?你必须得先弄清楚这几个包咱们晓得:core-js
是一种 polyfill
,它提供了旧版本浏览器缺失的 所有 的ES6+
API
的办法与实现。
在这里,以及下文,咱们把通过引入 core-js
的某个模块 ,来实现旧版本浏览器不反对的 某个 ES6+
API
的过程,叫做垫平。
咱们看看 core-js
这个包外面的次要一些模块:
es
:外面只蕴含有稳固的ES
性能。proposals
:外面蕴含所有stage
阶段的API
stable
:它外面蕴含了,只有稳固的ES
性能跟网络规范
所以,咱们能够这么应用:
- 当咱们只须要垫平 某个 稳固的
ES6+
API
,咱们能够用es
这个文件夹里的polyfill
来垫平(import X from 'es/xx'
) - 当咱们须要用到 提案阶段 的
API
时,我就用proposals
这个文件夹里的polyfill
来垫平(import X from 'proposals/xx'
) - 当咱们想垫平 所有稳固版本 的
ES6+
API
,能够导入用stable
文件夹(import 'core-js/stable'
) - 当咱们想垫平 所有 的
ES6+
API
(包含提案阶段),能够间接import 'core-js'
以上是我集体的应用习惯,因人而异,具体的介绍能够看看参考文章。
参考文章:core-js
再谈@bable/preset-env
通过上篇文章—— 想弄懂 Babel?你必须得先弄清楚这几个包,咱们晓得:
-
Babel
大体由两个性能组成:- 编译
ES6+
最新语法(let
、class
、() => {}
等) - 实现旧版本浏览器不反对的
ES6+
的API
(Promise
、Symbol
、Array.prototype.includes
等)
- 编译
-
@babel/preset-env
有以下两个性能:- 它 只编译
ES6+
语法 - 它并不提供
polyfill
,然而能够通过 配置 咱们代码运行的 指标环境 ,从而管制polyfill
的导入跟语法编译,使ES6+
的新个性能够在咱们想要的 指标环境 中顺利运行
- 它 只编译
-
@babel/plugin-transform-runtime
也有以下两个性能:@babel/runtime
跟@babel/plugin-transform-runtime
两者配合,能够缩小打包体积- 也有一个配置性能,用来解决
polyfill
如何垫平
- 如果咱们想要在旧浏览器用到
ES6+
API
时,咱们应该装置3
版本的core-js
(或者后续更高版本的);
那咱们能够很分明的晓得:
- 实现
Babel
第一个性能:咱们用@babel/preset-env
就能够了 - 实现
Babel
第二个性能:咱们就须要用core-js
这个包来提供polyfill
,并与@babel/preset-env
或者@babel/plugin-transform-runtime
的配置性能相互配合应用
咱们先来看看 @babel/preset-env
的配置项有哪些:
// babel.config.js
const presets = [
[
'@babel/preset-env',
{
modules,
targets,
corejs,
useBuiltIns,
spec,
loose,
debug,
bugfixes,
include,
exclude,
forceAllTransforms,
configPath,
ignoreBrowserslistConfig,
browserslistEnv,
shippedProposals
}
]
];
module.exports = {presets};
咱们能够看到配置项还是蛮多的(有一些配置项,前期可能会废除),然而,其实咱们平时我的项目中次要用到前四个配置,所以在这里咱们重点来看看前四个配置(能不学的尽量不学,太累了)。
参考文章:@babel/preset-env
modules
- 性能:启用
ES
模块语法向另一种模块类型的转换 - 默认值:
auto
- 可取的值:
"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false
当咱们设置成 false
的时候,Babel
编译产生的一些辅助函数的引入形式会变成 ES6
的模式引入(import A from 'B'
)。
咱们把 use-transform-runtime 这个案例 Babel
配置改成以下配置,感受一下 modules
这个配置的性能。
// babel.config.js
const plugins = ['@babel/plugin-transform-runtime']
const presets = [
[
'@babel/preset-env',
{modules: false}
]
];
module.exports = {plugins, presets};
在 没设置 modules
配置项 时,编译后的文件是:
咱们会发现辅助函数都是以 require
的形式引入的;
在 设置了 modules
配置项 后,编译后的文件是:
咱们会发现辅助函数变成了咱们相熟的 ES6
模块形式 import
引入。
这样有一个益处,就是咱们用一些像 Webpack
打包工具时,能够对代码动态剖析,很好地 tree shaking
缩小代码体积,所以咱们配置 Babel
的时候倡议设置modules: false
参考文章:modules
targets
作用
它的用法与 browserslist 统一。它能够用来设置咱们的代码须要兼容的 指标环境,因而它:
- 能够无效地缩小
ES6+
的语法编译 - 能够无效管制
polyfill
导入多少
留神
第一点
如果咱们没有设置这个配置项时,它会去咱们的 Babel
配置文件找 顶层的 targets
;如果顶层没有设置targets
,则会去咱们的package.json
里的 browserslist
或者根目录找.browserslistrc
;如果还没有则默认值为{}
。查找过程大抵如下,序号代表查找程序:
// Babel 配置文件
{
targets: 'ie 10', // 2. 如果 presets 外面没有设置 targets,会来这里查找
presets: [
[
'@babel/preset-env',
{targets: 'ie 9' // 1. 先在这里查找,没的话去顶层 targets 查找}
]
]
}
// package.json
{
...,
browserslist: ['ie 11' // 3. 如果顶层 targest 外面没有设置,会来这里查找;如果这里也没设置,则为默认值{}
]
}
第二点
如果咱们没有设置这个配置项时,Babel
会假如咱们要兼容的指标环境是最旧的浏览器,所以会将所有的 ES6+
语法代码转化为 ES5
。 所以咱们配置 Babel
的时候,要设置 targets
以缩小输入代码大小。
针对这点,咱们用这个案例 preset-env-targets-config 来感受一下:
咱们会发现 ES6+
的写法全副被转成了ES5
,还退出了一些辅助函数(红色框)。
ok,咱们设置 targets: 'chrome 80'
。这示意,咱们的代码是要在chrome 80
上运行的,再看看打包后的后果:
咱们会发现编译进去的代码,跟咱们入口文件写的代码根本没差。因为 chrome 80
曾经实现了入口文件代码的写法了。所以,如果咱们的代码不须要在一些比拟低端的浏览器跑的话,设置 targets
就非常有必要。
参考文章:targets
corejs
当 useBuiltIns
不为 false
的时候,须要设置这个配置项
配置
它有两种配置形式:
-
间接设置
core-js
版本号... { useBuiltIns: 'usage', corejs: '3.27.2' } ...
-
配置
corejs
... { useBuiltIns: 'usage', corejs: { version: '3.27.2', // 是否编译提案阶段 ES6+ API proposals: false }, } ...
留神
- 当咱们的
useBuiltIns
不为false
的时候,须要设置corejs
这个配置项 2
版本的core-js
曾经不倡议应用了;咱们用当然要用最新的,目前最新的版本是core-js@3.27.2
- 咱们装置的
core-js
要尽量放弃最新,因为越新的包,蕴含的polyfill
才会越多 - 咱们设置
corejs
的版本号时,不要间接指定2
或者3
,它会被解析为2.0
或者3.0
。所以,咱们应该带上 子版本号(3.27.2
),这样才会有最新的polyfill
-
core-js
默认用 稳定版 的polyfill
来垫平,但如果有时咱们想用还处在提案阶段的API
怎么办?- 如果咱们配置的是
useBuiltIns: entry
,咱们得手动引入core-js
提案的polyfill
来垫平。提案的polyfill
放在core-js/proposals
文件夹中(import 'core-js/proposals/array-last'
) - 如果咱们配置的是
useBuiltIns: 'usage'
,则咱们用下面说的corejs
模块外面提到的第二种配置形式,把proposals
设为true
就能够了
- 如果咱们配置的是
它的作用会联合上面的 useBuiltIns
一起讲。
参考文章:targets
useBuiltIns
下面咱们提到了,咱们把通过引入 core-js
的某个模块 ,来实现旧版本浏览器不反对的 某个 ES6+
API
的过程,叫做垫平。
这个配置就是用来设置咱们 core-js
的垫平形式的。它有上面三个值:
为了更好的了解,咱们用
Promise
这个ES6+
API
作为上面的例子。咱们都晓得:
IE 11
并不反对Promise
Promise
这个对象其实还有很多办法,例如Promise.any
、Promise.all
、Promise.finally
等。- 咱们用这个案例 preset-env-useBuiltIns-config 来解说
entry
咱们能够这么了解,entry
中文是“进入”的意思,这个值阐明咱们的 polyfill
应该是须要从某个 入口 引入来垫平。
体现
咱们把配置设置为:useBuiltIns: 'entry'
- 咱们先来看看这个配置在
IE 11
的表现形式,咱们设置targets: 'ie 11'
: - 咱们再把
targets
设置成chrome: 80
看看体现:
剖析
-
在
IE 11
的体现咱们
import 'core-js/es/promise'
(相当于import
某块polyfill
来垫平),因为咱们的IE 11
不反对Promise
,所以useBuiltIns: 'entry'
配置把咱们 所有 不反对的Promise
办法都垫平了(打印的window.Promise.any
有值)。 -
在
chrome 80
体现咱们
import 'core-js/es/promise'
(相当于import
某块polyfill
来垫平),因为在chrome 80
中,Promise
大部分办法曾经实现,只有Promise.any
没有实现,所以此时只垫平了promise.any
办法。
总结
所以咱们能够总结出,它的执行原理大抵是这样的:
- 咱们须要 手动
import
所有 或者 某块polyfill
Babel
会依据咱们设置的targets
(指标环境),来判断咱们手动import
的所有 或者 某块polyfill
是不是以后缺失的- 如果是的话,就会把咱们手动
import
所有 或者 某块polyfill
,拆分成很多小模块, 引入咱们指标环境不反对的模块
留神
- 为了防止一些奇奇怪怪的问题,咱们手动
import
的polyfill
应该 对立在入口文件(咱们当初的工程项目个别都会有一个入口文件) - 如果咱们想一劳永逸,间接把以后环境 所有 不反对的
ES6+
API
垫平,那咱们就import 'core-js/stable'
(这会垫平以后targets
不反对的所有稳固版本的ES6+
API
,所以也会导致包变大) - 如果咱们只想单纯垫平 某个
ES6+
API
(前提是targets
不反对这个API
,否则手动import
了也没用;例如只想垫平Promise
),那咱们import 'core-js/es/promise
就能够了 - 如果想垫平提案阶段的
API
,则也须要手动import
对应提案的polyfill
(import "core-js/proposals/string-replace-all
)
参考文章:usebuiltins
usage
这个值的作用,就是咱们不须要手动 import
,它会主动帮咱们import
以后 targets
缺失的polyfill
。
体现
咱们把配置设置为:useBuiltIns: 'usage'
- 咱们先来看看这个配置在
IE 11
的表现形式,咱们设置targets: 'ie 11'
:
! - 咱们再把
targets
设置成chrome: 80
看看体现:
剖析
-
在
IE 11
的体现咱们不必本人手动
import
相干polyfill
,咱们的代码中只用到了繁多的Promise
对象,所以 只垫平 了Promise
这个对象,不会垫平它其余相干的办法(打印的window.Promise.any
无值)。 -
在
chrome 80
的体现咱们不必本人手动
import
相干polyfill
,此时没有任何对于Promise
的垫平,因为繁多的Promise
对象在chrome 80
曾经实现,且咱们代码中没有用Promise.any
办法,天然也就不会垫平Promise.any
。此时代码只垫平了提案阶段的array.lastItem
办法,因为chrome 80
不反对它,并且咱们代码中用到了它。
总结
所以咱们能够总结出,它的执行原理大抵是这样的:
- 咱们 不须要手动
import
所有 或者 某块polyfill
Babel
会依据咱们以后代码中用到的ES6+
API
,并判断以后的targets
支不反对咱们用到的这个ES6+
API
- 如果不反对的话,则 主动导入这个
ES6+
API
对应的polyfill
因为它会主动导入,所以咱们专一写咱们的 ES6+
就好了。
参考文章:usebuiltins
false
它是默认值。它示意不要在每个文件中主动增加 polyfill
,也 不会依据 targets
判断 缺不缺失,也不会将咱们手动 import
所有 或者 某块 polyfill
拆分为单个 polyfill
引入。
体现
咱们把配置设置为:useBuiltIns: false
- 咱们先来看看这个配置在
IE 11
的表现形式,咱们设置targets: 'ie 11'
: - 咱们再把
targets
设置成chrome: 80
看看体现:
总结
useBuiltIns
设置为false
:
- 对咱们的垫平形式没作用,源码是什么样,输入就是什么样
- 设置
targets
有效
参考文章:usebuiltins
应用
适配 IE 11
置信通过下面的解说,咱们对各个配置项有个大略的理解了,那咱们再更深刻体验一下。
咱们都晓得 IE 11
根本是不反对 ES6+
的,咱们抽几个罕用的 ES6+
API
看看:
那咱们就用 IE 11
作为咱们的 targets
(指标环境),钻研一下如何配置Babel
,使咱们写的ES6+
代码能在 IE 11
中跑起来。咱们用这个案例 preset-env-template-config
留神:
为了防止Webpack
打包谬误,咱们把targets
写在package.json
中,这样Webpack
能力辨认环境打包... "browserslist": ["ie 11"] ...
咱们用一下这段代码作为咱们的入口文件:
// 如果用 `usage` 形式,则正文掉这段代码
import 'core-js/stable';
const lMC = {
name: 'limingcan',
like: ['eat', 'drink', 'play', 'fun'],
breath() {
return new Promise(resolve => {setTimeout(() => resolve(), 1000)
})
}
};
lMC.breath().then(() => console.log('breath'));
console.log(lMC.like.includes('play'));
console.log(Array.of(1, 2, 3));
依据咱们下面几个配置项的解说,如果咱们想:
-
一劳永逸的间接垫平
targets
所有不反对的ES6+
API
,那咱们的配置应该是:const presets = [ [ '@babel/preset-env', { modules: false, useBuiltIns: 'entry', corejs: { version: '3.27.2', proposals: true } } ] ]; module.exports = {presets};
此时
IE 11
失常输入:红色框是咱们源码中 没用到的
ES6+
API
,也都被垫平了;此时包的大小有115K
-
如果咱们想缩小包的体积,只垫平咱们用到的
ES6+
API
,那咱们的配置应该是:const presets = [ [ '@babel/preset-env', { modules: false, useBuiltIns: 'usage', corejs: { version: '3.27.2', proposals: true } } ] ]; module.exports = {presets};
此时
IE 11
失常输入:然而咱们会发现,红色框是咱们源码中没用到的
ES6+
API
,它并没有被垫平的,它只会垫平咱们代码中用到的API
;此时包的大小只有29K
常见问题
通过下面的例子,咱们会发现:
如果配置是useBuiltIns: 'entry'
- 咱们垫平的
polyfill
,都是注入到window
全局的,或者是某个内置对象的原型(prototype
)上,这 影响到了全局 - 一劳永逸的形式会垫平以后
targets
所有不反对的ES6+
API
,这尽管不便,但这会导致 包变得很大
如果配置是useBuiltIns: 'usage'
- 它也会将垫平的
polyfill
注入到全局。 - 因为
useBuiltIns: 'usage'
是判断以后targets
支不反对咱们代码中用到的ES6+
API
,如果不反对会本人import
。
那有这样一种状况,如果第三方库用到了咱们以后targets
不反对的ES6+
API
,但咱们本人的代码没有用到这个API
,那么这个API
是不会被叠平的,这会导致咱们我的项目报错。
第三方库问题
针对 useBuiltIns: 'usage'
配置的第二点弊病,咱们来看这个例子 use-third-party-library-problem 更间接的感受一下。
咱们把 targets
设为 IE 11
,咱们 本人的代码只用 includes
这个 ES6+
API
,而后再用第三方库 tars-utils 的optimizeImage
办法,生成一个 Blob
对象(外面是用 Promise
实现的)。
咱们在 IE 11
跑一下看看:
通过 Babel
编译后的文件,咱们会发现:
- 只有咱们代码中应用的
includes
办法被垫平; - 第三方库中用到的
Promise
并没有被垫平,所以导致IE 11
报错了。这是一个十分事实的问题。
咱们在高级一点的浏览器(chrome 108
)看看:
在 chrome 108
运行没有任何问题,因为 chrome 108
曾经外部实现了Promise
。
总结
看到这里,置信咱们对 @babel/preset-env
的配置性能曾经有个大略的理解了。上述所说的问题的确是咱们很理论的问题。
因而,useBuiltIns
设置 entry
还是usage
,还是得依据咱们我的项目理论需要来,我集体倡议:
- 因为咱们
@babel/preset-env
配置形式,是会把以后targets
缺失的API
注入到全局 ,所以这个配置形式是比拟适宜咱们做的一些 前端工程项目 或者 应用程序 。如果对包的体积不是很在意,倡议应用useBuiltIns: entry
的形式,而后再import 'core-js/stable'
,一劳永逸的垫平,这样能够帮咱们防止掉一些奇怪的问题, - 如果应用
useBuiltIns: usage
,那还是得留神第三方库的问题。如果判断出哪块polyfill
缺失,咱们能够本人手动import
去垫平
再谈@babel/plugin-transform-runtime
下面说到,@babel/preset-env
配置形式,是会把以后浏览器缺失的 API
注入到全局的 ,那么有没有不注入全局的方法呢?答案是有的。它就是咱们接下来要讲的@babel/plugin-transform-runtime
配置。
咱们先来看看它有几个配置项(谢天谢地,不算很多):
// babel.config.js
const plugins = [
[
'@babel/plugin-transform-runtime',
{
helpers,
regenerator,
corejs,
version
}
]
];
module.exports = {plugins};
helpers
&& regenerator
解析
咱们先看前两个配置,因为前两个配置比较简单,咱们放在一起讲。
helpers
默认值是:true
regenerator
默认值是:true
通过上篇文章——想弄懂 Babel?你必须得先弄清楚这几个包,咱们晓得:
对于@babel/runtime
@babel/runtime
是 寄存了Babel
辅助函数的一个汇合包
对于辅助函数
- 当咱们只用了一些
ES6+
语法糖的时候,Babel
编译时会内联注入一些辅助函数 @babel/plugin-transform-runtime
与@babel/runtime
配合应用时,会将咱们用到的辅助函数,从@babel/runtime
中以require
或者import
的形式,引入到咱们的文件中,实现复用,从而减小咱们最终输入包的体积。
对于regenerator
- 咱们的源码外面应用了
async function() {}
等异步函数,或者fuction* myGenerator() {}
这种Generator
函数的话,就会须要用到regenerator-runtime
这个包来编译。 Babel >= 7.18.0
,regenerator-runtime
包里的内容,会以 局部变量的形式内联注入到咱们的代码中 ,这样咱们就不须要全局提供一个regeneratorRuntime
对象。
例如咱们应用了 class
语法糖跟 async function() {}
,而后用@babel/runtime
跟@babel/plugin-transform-runtime
(默认状况下,helpers
与 regenerator
值为true
)配合应用,编译后如下图:
当咱们把 helpers
跟regenerator
的值设为false
:
咱们会发现咱们的辅助函数,跟 regenerator-runtime
这个包又变回了内联形式。所以:
-
helpers
:管制的是咱们的辅助函数,是否不内联 进咱们的代码中。true
的话是不内联,而是援用@babel/runtime
辅助函数汇合包false
的话,则会内联
-
regenerator
:与helpers
相似,管制的是咱们regenerator-runtime
这个包的代码,是否不内联 进咱们的代码中。true
的话是不内联,而是援用@babel/runtime
辅助函数汇合包false
的话,则会内联
留神
官网中对于 regenerator
的解释,大抵意思是:regenerator
如果设为 false
,须要咱们提供一个全局的regeneratorRuntime
的对象。
然而:
- 当
Babel >= 7.18.0
当前,regenerator-runtime
包里的内容,会以 局部变量的形式内联注入到咱们的代码中 。所以其实Babel >= 7.18.0
regenerator
这个配置项集体感觉是根本没用了 Babel < 7.18.0
的话,则须要咱们提供一个全局的regeneratorRuntime
的对象。相干案例可查看 import-regenerator-runtime,开启babel.config.js
相干正文代码。
corejs
解析
corejs
这个配置项一旦不为 false
,就是用来设置咱们的要垫平的ES6+
API
,以 不净化全局局部变量形式垫平。
它有三个值:
值 | 对应依赖 | 补充 |
---|---|---|
false (默认值) |
@babel/runtime |
|
2 |
@babel/runtime-corejs2 |
1. 只能编译反对全局变量(如Promise )和动态属性(如Array.from );<br/>2. 不能编译实例相干办法([].includes ) |
3 |
@babel/runtime-corejs3 |
1. 既能编译能编译反对全局变量和动态属性,又能编译实例办法 2. 开启 proposals: true ,还能够编译提案阶段的API |
咱们用这个例子 transform-runtime-config 体验一下。
-
如果配置的是
corejs: 2
的话,会怎么样:咱们会发现,实例办法
includes
没被垫平,提案API
(Math.signbit
)也没有被垫平;Promise
是以局部变量的形式呈现在咱们的代码中。 - 咱们再看看配置的是
corejs: {version: 3, proposals: true}
:
咱们会发现,实例办法 includes
被垫平,提案 API
(Math.signbit
)也垫平;但它们都以 局部变量 的形式注入。
所以,如果咱们不想以全局的形式净化的形式垫平咱们的 ES6+
API
,咱们corejs
就不能为 false
,并且优先应用@babel/runtime-corejs3
这个包来垫平(设置为3
)
优化
下面的案例咱们并没有设置 targets
,所以@babel/plugin-transform-runtime
配置下,会把咱们代码中用到的 所有 ES6+
API
都垫平。咱们来设置 targets
,看看能不能垫平咱们的targets
不反对的ES6+
API
。
咱们在 package.json
外面增加,或者在 配置文件的顶层 增加是能够的(通过测试,在 @babel/preset-env
外面设置 targets
是不行的):
// package.json
"browserslist": ["chrome 80"]
// 或者在顶层增加
module.exports = {targets: {chrome: 80}, // 在这里增加
presets: ['@babel/preset-env'],
plugins: [
[
"@babel/plugin-transform-runtime",
{...}
]
]
}
输入:
咱们会发现,Promise
跟 includes
都没有被垫平,因为 chrome 80
曾经反对了
总结
@babel/preset-env
是以全局形式垫平,@babel/plugin-transform-runtime
是以局部变量形式垫平,两者咱们应该抉择其一,不要又用@babel/preset-env
配置形式,又用@babel/plugin-transform-runtime
配置形式,这样必定会呈现一些奇奇怪怪的问题。- 因为应用
@babel/plugin-transform-runtime
垫平是以 局部变量的形式 来垫平,所以@babel/plugin-transform-runtime
这种配置形式更适宜来做 库 的开发。它能够很好的帮咱们的库与使用者的我的项目解耦。
参考文章:babel-plugin-transform-runtime
其余
-
案例 preset-env-useBuiltIns-config 外面有个
stage-1
阶段的提案API
—— Array.prototype.lastItem(取数组最初一项)。原本是想用Array.prototype.uniqueBy
这个以后处在stage-1
的API
来给大家做例子的,后果发现编译当前在IE 11
有问题。所以给Babel
提了个 issues:目前应该是修复了,在等合并。复现问题的代码包在 babel-use-proposals-problem,感兴趣的敌人也能够
Fork
本人瞅瞅。说这个事次要也是想表白,学习还是不能进行(不是卷啊,还是要有学习的习惯)。 -
在讲
@babel/plugin-transform-runtime
如何配置时,咱们说到开启{version: 3, proposals: true}
时,能够以局部变量的形式对提案阶段的ES6+
API
垫平。然而通过测试发现,有些提案阶段的
API
,用这个办法仿佛是不能按预期实现的,所以又提了个 issues,有个Babel
之一的大佬说能够用babel-plugin-polyfill-corejs3
来实现:对于
babel-plugin-polyfill-corejs3
这块,其实Babel
还有一种垫平配置形式,是应用 babel-polyfills 这个包来实现的,这块前期再看看要不要出文章聊聊。
最初
通过以上的理解,咱们最初来总结一下这个配置。
-
如果咱们开发的我的项目是 应用程序 ,或者 大型的我的项目,那咱们能够这么配置:
// Babel 配置 const presets = [ [ '@babel/preset-env', { modules: false, // 或者只想用垫平咱们代码中用到的 --> useBuiltIns: 'usage', useBuiltIns: 'entry', corejs: { version: '3.27.2', proposals: true } } ] ]; const plugins = ['@babel/plugin-transform-runtime']; module.exports = {plugins, presets}; // package.json { ..., // 设置指标环境 "browserslist": ["ie 11"] } // 入口文件 // ---- useBuiltIns: 'entry' 时,须要引入以下 ---- // 垫平全副 ES6+ 稳定版 API import 'core-js/stable'; // ---- 或者 ----- // 垫平所有 ES6+ API,包含提案阶段 import 'core-js';
—
-
如果咱们是想开发一个 第三方库,咱们能够这么配置:
// Babel 配置 const presets = [ [ '@babel/preset-env', {modules: false} ] ]; const plugins = [ [ '@babel/plugin-transform-runtime', { corejs: { version: 3, proposals: true } } ] ]; module.exports = {plugins, presets}; // package.json { ..., // 设置指标环境 "browserslist": ["ie 11"] } // 入口文件 const Method = {wait(delay) {return new Promise(resolve => setTimeout(() => resolve(), delay); } } ...
文章波及到的例子,曾经上传 Github,感觉有帮忙的话,欢送 Star
或者 Fork
学习。
如果读完这篇文章的你,感觉真的有帮忙到,欢送点赞珍藏 ;如果有异同点, 欢送在评论区探讨。
本文参加了 SegmentFault 思否写作挑战赛,欢送正在浏览的你也退出。