You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1、corejs 是一个给低版本的浏览器提供接口的库,如 Promise, map, set 等。在 babel 中你设置成 false 或者不设置,就是引入的是 corejs 中的库,而且在全局中引入,也就是说侵入了全局的变量。
2、如果你的全局有一个引入,不要让引入的库影响全局,那你就需要引把 corejs 设置成 2。 所以一旦你使用了2这个参数就必须引入@babel/runtime-corejs2
3、@babel/plugin-transform-runtime是必须装的,如果corejs设置为2的话安装@babel/runtime-corejs2来代替@babel/runtime,反正设置为false的话就需要@babel/runtime,根据你的设置来安装即可。
4、所以@babel/runtime和@babel/runtime-corejs2区别就是后面那个多了个corejs2的包。与@babel/runtime区别,官网是这样描述的Difference from @babel/runtime:This can be used instead of a polyfill for any non-instance methods. It will replace things like Promise or Symbol with the library functions in core-js
// 转换前
let a = [1, 2, 3];
let b = () => {
console.log('这是箭头函数!');
}
let c = [...a];
// 转换后
let a = [1, 2, 3];
let b = () => {
console.log('这是箭头函数!');
}
let c = [...a];
"use strict";
require("core-js/modules/es6.array.copy-within");
require("core-js/modules/es6.array.every");
require("core-js/modules/es6.array.fill");
..........
require("core-js/modules/web.timers");
require("core-js/modules/web.immediate");
require("core-js/modules/web.dom.iterable");
require("regenerator-runtime/runtime");
var a = [1, 2, 3];
var b = function b() {
console.log('这是箭头函数!');
};
var c = [].concat(a);
b();
var d = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("ok");
}, 2000);
});
d.then(function (res) {
console.log(res);
});
"use strict";
require("core-js/modules/es6.promise");
require("core-js/modules/es6.object.to-string");
var a = [1, 2, 3];
var b = function b() {
console.log('这是箭头函数!');
};
var c = [].concat(a);
b();
var d = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("ok");
}, 2000);
});
d.then(function (res) {
console.log(res);
});
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var a = [1, 2, 3];
var b = function b() {
console.log('这是箭头函数!');
};
var c = [].concat(a);
b();
var d = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("ok");
}, 2000);
});
d.then(function (res) {
console.log(res);
});
var MM = function MM() { // 这个是我转换前用class定义的类 class MM {constructor(){}} 这种
(0, _classCallCheck2["default"])(this, MM);
};
// index.js,是我要转换的文件
import '@babel/polyfill';
let a = `hello, can you hear me!`;
let func = () => {
console.log('这是箭头函数');
}
let b = [1, 2, 3];
let c = [...b];
let array = [1];
console.log(array);
let promise_t = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(233);
}, 2000)
});
promise_t.then((res) => {
console.log(res);
})
class Test {
constructor(name) {
this.name = name;
}
print() {
console.log(this.name);
}
}
let t_t = new Test('xiaohong');
t_t.print();
这儿我单独安装一次regenerator-runtime就不会报错了,暂时没找到原因,试着在安装了regenerator-runtime的情况下使用usage参数值,同时去除index.js里面的import 'core-js'这句话,不然会报警告。内容像这样:When setting useBuiltIns: 'usage', polyfills are automatically imported when needed.
Please remove the import '@babel/polyfill' call or use useBuiltIns: 'entry' instead.。我试了下,使用webpack打包没得问题,可以运行。这儿建议把regenerator-runtime安装一次,避免不必要的麻烦。
一、Babel相关的概念
1、@babel/core与babel-core区别
2、.babelrc和babel.config.js
3、@babel/polyfill和@babel/plugin-transform-runtime和@babel/runtime和@babel/runtime-corejs2(都是用来转换新Api的)
在babel 7下:
默认情况下.babelrc不作用于子包,那么在babel.config.js下加入一下babelrcRoots来指定即可。
一文读懂 babel7 的配置文件加载逻辑
对babel-transform-runtime,babel-polyfill的一些理解
babel7中 corejs 和 corejs2 的区别
babel preset env配置
babel学习笔记
二、Babel配置入门指南
首先需要本机安装node.js,使用npm包管理工具来初始化目录,本次操作学习都是在Babel 7上进行的,相较于Babel 6还是有一定区别,单独使用Babel 7需要CLI来完成,所以先安装脚手架和核心@babel/core。
安装完成后,我们就可以使用cli提供的命令来转换我们的JS代码了,比如建立一个test.js的JS文件,里面包含ES6的内容:
然后来一波命令:
不想每次需要什么插件都去手动引入插件,所以我们就需要祭出@babel/preset-env,先安装这个工具。
然后在根目录建一个babel.config.js来配置babel,在文件中加入以下内容:
之后我们再运行一次上面的转换命令,可以得到以下代码:
这样ES6新的语法糖就转换成ES5了。
当然,babel.config.js里面还可以指定目标,当满足什么样的条件才去转换语法,不指定targets的情况下,默认是把所有的ES6+都转换成ES5,比如下面的示例:
这种只有当在大于ie 8以上的浏览器不支持的语法才会转换。
@babel/polyfill
babel只能转换一般的语法糖,不能转换新的API,所以就只能祭出polyfill来弥补。首先安装下polyfill,然后引入就可以了。
然后在JS文件里面引入
对于使用webpack的同学,可以直接在main入口直接引入,打包过后直接可以使用,如下:
@babel/preset-env 加强
上面的引入方法是完全引入,导致包非常大,我们可以按需引入,这里又要配置@babel/preset-env,修改babel.config.js代码如下:
然后运行一下会看到这些代码:
它会一股脑的把所有的包全部引进来,这样嘿不科学,所以usage参数可以做到按需引入,它只会引入相关的包,没使用的ES6+API不会引入相关的包,修改babel.config.js代码:
转换过后的代码如下:
这样,我们可以看到,我的代码使用了promise,它就只引入promise相关的代码。
到这儿,问题来了,在使用usage参数后使用babel的cli命令工具(也就是这个:npx babel test.js --watch --out-file test-done.js)会给一段提示,告诉我们要指定core-js@2或者core-js@3,从babel 7.4过后官方就建议这么做了,就是让我们放弃@babel/polyfill,我先卸载掉@babel/polyfill试一试,发现还是能转换,不科学,然后查资料和看preset-env文件夹下才发现,人家自带了polyfill,所以这儿如果有了@babel/preset-env不需要单独安装@babel/polyfill了,前提应该是使用了@babel/preset-env配置了babel才行(像前面的完全引入polyfill还是需要单独安装@babel/polyfill),(注意:这儿我试了使用webpack结合babel-loader在不单独安装@babel/polyfill或者core-js这些打包会出问题,"useBuiltIns": "usage"时提示找不到包,使用entry参数打包不报错,直接不会导入包,所以环境不一样不能一概而论)。 前面有个要我们指定corejs的提示,也只需要在babel.config.js里面指定一下就可以了,这儿我的@babel/perset-env版本是7.6.3,不知道其它版本有没有集成polyfill,babel.config.js代码如下:
这儿我测试了下指定corejs为2和3时引入的代码不一样,暂时没了解到原因-_-。
@babel/runtime、 @babel/plugin-transform-runtime
接下来走一波不污染全局的配置方式,前面的配置都是要污染全局,还是不怎么科学,关于这种方式的优点和缺点大家上网查一下就可以了,接下来先安装好包:
上面这个安装到dev依赖就可以了,不用于生产环境
接下来我们配置一下babel.config.js,如下:
然后输出一下
发现输出的代码里面没得polyfill了。如果需要polyfill的话就要单独安装以下内容:
这里安装这个包之前把我@babel/runtime给卸载了,安装完成后再重新配置一下babel.config.js,如下:
然后运行一下,看结果。相比前面的@babel/runtime,这里的polyfill回来了,多了一句这个
参考资料
babel-runtime VS babel-polyfill
结合Babel 7.4.0 谈一下Babel-runtime 和 Babel-polyfill
三、结合到webpack来使用
结合webpack的话,还需要以下几个东西:
babel-loader是加载器,要结合webpack来使用的话,这个必须要,同时,在项目根目录建立一个
webpack.config.js
配置文件(这里webpack的知识就不介绍了,详情参考官网)。还是借助@babel/preset-env
首先我还是先测试了参数为entry的情况,配置文件内容如下(注意:这儿我还安装了@babel/polyfill):
然后是webpack.config.js文件
之后再是babel.config.js文件
这儿我发现,即使我的babel.config.js不配置
'useBuiltIns': 'entry',
这句,打包出来的main.js虽然内容有差别,但是还是能运行成功,IE11亲测可用上面js的promise语法。暂时我还没把useBuiltIns这个属性搞的特别清楚,只是知道在使用usage
属性值时可以按需加载polyfill。接下来使用
'useBuiltIns': 'usage'
来试一试,我发现在保持其他文件不变的情况下,(这儿有个问题是,使用usage时在index.js中还是要写这句import '@babel/polyfill',不然找不到包,这与我上面单独使用babel来转换时说不在单独引入polyfill有点出入,还没怎么明白,后期我会补充)。然后我比较了两种方式生成的main.js的代码,使用entry属性值时,main.js代码八千多行,大小大概250kb,使用usage参数时,代码一千多行,大小大概37kb,所以按需引入效果还是明显。而且亲测在IE11上两种方式生成的代码均可正常运行。使用core-js代替@babel/polyfill
官方网站上面说从babel 7.4.0后开始放弃babel/polyfill,转而使用core-js。这儿我们又来试一试core-js
首先卸载@babel/polyfill,然后执行以下命令安装core-js@2:
这儿还有个core-js@3的版本,暂时没有用过,不知道区别。安装完成后修改一下babel.config.js
然后你的index.js的上面去掉
import '@babel/polyfill'
,这时执行过后的main.js能完美运行在IE11上,而且这儿也不需要手动引入core-js@2,使用usage属性值时自动按需引入,比较稳。如果我不写'corejs': 2
这个参数,转换也可以成功,但是会报warning,叫我去安装core-js并制定版本,问题不大,还是写上,毕竟官方要求。然后如果我直接把useBuiltIns的参数值改为entry,发现class这些es6语法会转换,但是Promise的polyfill没有引入,看来没usage参数好使,需要手动引入才行,我在index.js手动引入import 'core-js',
然后执行webpack但是却报错,提示
Module not found: Error: Can't resolve 'regenerator-runtime/runtime'
,这个就尴尬了,还要安装regenerator-runtime/runtime,但是使用usage却没有出现这个问题,暂时无解,这儿我单独安装一次:这儿我单独安装一次regenerator-runtime就不会报错了,暂时没找到原因,试着在安装了regenerator-runtime的情况下使用usage参数值,同时去除index.js里面的import 'core-js'这句话,不然会报警告。内容像这样:When setting
useBuiltIns: 'usage'
, polyfills are automatically imported when needed.Please remove the
import '@babel/polyfill'
call or useuseBuiltIns: 'entry'
instead.。我试了下,使用webpack打包没得问题,可以运行。这儿建议把regenerator-runtime安装一次,避免不必要的麻烦。1、不安装core-js和regenerator-runtime,不论你的@babel/preset-env的useBuiltIns设置为哪个参数值都不能打包成功,
usage
参数值提示找不到core-js的包,entry
直接不会引入相关的东西,因为包都没有,会提示你去下载corejs。false
效果跟entry一样。2、只安装了core-js(这儿安装的core-js@2版本),
usage
参数可以打包成功,但是提示指定core-js版本,这个正常,因为我没写那句'corejs: 2'
了,测试在IE11上正常运行。entry
参数需要手动在index.js中引入core-js,打包提示Can't resolve 'regenerator-runtime/runtime'
,打包失败,false
参数打包成功,但是文件巨大,代码九千多行-_-,IE11运行成功。3、安装core-js和regenerator-runtime,
usage
参数可以打包成功,但是提示指定core-js版本,这个正常,因为我没写那句'corejs: 2'
了,测试在IE11上正常运行。entry
参数可以打包成功,但是提示指定core-js版本,这个正常,因为我没写那句'corejs: 2'
了,测试在IE11上正常运行,打包过后文件巨大,我安装了regenerator-runtime,没有在index.js里面手动引入,只引入了core-js,这次打包没报上面找不到包的错误。false
参数可以打包成功,但是提示指定core-js版本,这个正常,因为我没写那句'corejs: 2'
了,测试在IE11上正常运行,打包过后文件巨大。所以我得出一个配置结果
在babel.config.js里面这样写:
package.json里面包含这些包:
core-js和regenerator-runtime(这个为了避免entry参数时包错找不到包)都安装起。这样就可以了。
使用@babel/plugin-transform-runtime和@babel/runtime-corejs2来实现API的polyfill
前面使用了@babel/preset-env的useBuiltIns来实现API填充,这儿试一试另一种方案,首先卸载掉core-js和regenerator-runtime,然后安装一下两个包
安装完成后配置一下babel.config.js
注意:这儿我是安装的@babel/runtime-corejs2,所以“'corejs': 2”这个参数不能少,否者会报 Can't resolve '@babel/runtime/helpers/createClass'这种错误,上面这种方式不会污染全局,适合第三方开发。
四、总结
暂时babel就总结到这儿了,顺便熟悉了一下webpack,如有不准确的地方还请各位多多指正,文章里面还有几个没理解清楚的地方,后期再琢磨琢磨!
The text was updated successfully, but these errors were encountered: