babel学习笔记

先是看到前端早读课【第1065期】再见,babel-preset-2015,据说如今有了babel-preset-env,别的什么preset都不须要了,还能够经过useBuiltIns设置成usage,只须要install一下babel-polyfill,其余全交给babel处理就好了。
看完屁颠屁颠得去拿本身项目开刀把preset换了,把import "babel-polyfill"删了,把babel-transform-runtime啊,preset-2015啊,preset-stage-2啊这些再也不须要的包都卸了,结果各类报错,心灰意冷。。。确定是本身哪儿弄错了,算了仍是忙别的去吧有空再折腾。。。前端

前两天又看到前端早读课推了一篇很长的【第1089期】babel到底该如何配置。边看,边跟着作了一遍,做者真的很用心,在github上放了配套的demo,看完以后我靠叫一个豁然开朗,回头再瞅瞅那边《再见babel-preset-2015》,多少有些遗漏细节,甚至有些误导人。git

通过一番折腾,总算是把本身项目里的babel配置调整好了,全部js文件从原来的1.85m缩小到1.62m。效果还挺好的。折腾了很多时间,改动其实就一个地方,就是配置文件.babelrc,记录一下本身折腾的过程。es6

plugins: ["transform-runtime"] 与 babel-polyfill

最开始没弄清楚配置文件里的"plugins": ["transform-runtime"]是干吗的,《babel到底该如何配置》说得很是清楚,babel就是经过其各类plugins来实现将指定的js转换成本身想要的样子,好比只要转换箭头函数,就只须要先安装对应的plugingithub

npm install --save-dev babel-plugin-transform-es2015-arrow-functions

而后加到plugins里面web

"plugins": ["transform-es2015-arrow-functions"]

这样babel就能转换箭头函数了。npm

transform-runtime插件和babel-polyfill所实现的结果同样,能够转换像Object.assign啊,Array.prototype.includes啊这类在es原生对象上的扩展方法,但实现的原理彻底不一样。babel-polyfill是直接在对象的prototype上进行同名方法扩展来实现和es6相同的功能,因此只须要全局引入一次babel-polyfill,本身的代码就不用作任何处理就能在低版本浏览器上执行了。
而transform-runtime插件作的事情,是改写每个用到es6扩展方法的地方,让其实现es6方法相同的功能。举个例子:
在使用babel-polyfill的时候,js里须要这么写:浏览器

import "babel-polyfill";
let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};
let arr2 = Array.from(arrayLike);

而后就没而后了,甚至都不用执行babel,只要install过babel-polyfill就够了。由于babel-polyfill中会用ES3的方式实现一遍Array.from方法,因此,以后整个项目用到Array.prototype.includes的时候,都不会再须要babel作任何事情,直接在低版本上浏览器执行includes方法吧,安全省心。安全

换成是用"transform-runtime"插件就是另一回事儿了。咱们的js文件里不须要引入babel-polyfill,但babel这时候就要开始干活了,他会把这段代码改写成:babel

import _Array$from from 'babel-runtime/core-js/array/from';
let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};
let arr2 = _Array$from(arrayLike); // ['a', 'b', 'c']

用babel-runtime里的方法去实现Array.from,而后把js文件里全部用到Array.from的地方全都替换掉。函数

本觉得那这两种方式取其一就好了。但后来发现transform-runtime是不会去替换Array.prototype.includes这中实例方法的,因此还得全局引入babel-polyfill,这样一来transform-runtime感受完全变成了一个多余的东西,除非整个项目里不用es6的原生类实例方法。因此最终,直接卸了transform-runtime。

presets 和 "presets": ["env"]

presets的用处也是看《babel到底该如何配置》搞清楚的,大体就是plugins的各类组合。也就是说,没有presets也无所谓,可是要很是清楚项目里用到了那些es6甚至更高级的功能,而后找到相应的plugin引入到plugins配置项里,这样也OK,但估计不太会有人吃饱了撑的干这种事情。

以前的presets有2015,2016,stage-1~4(对应处于提案的四个阶段的各个功能)等等,其实就是把相应的功能对应的plugins组合一下起个名字。好比要用es6的全部功能,只要在presets里配置一下

"presets": ["es2015"]

若是要用es6和全部处于提案第二阶段的功能

"presets": ["es2015","stage-2"]

好了,到这里,说说那个困扰我很多时间的babel-preset-env,我觉得这个preset只要告诉他要支持那个版本的浏览器,他就会把相关的全部的plugins都引入进来,因此屁颠屁颠把其余preset和全部plugins都删了。结果打包的时候报错了。缘由是我在项目里用了Vuex里推荐的处于stage-3阶段的对象展开运算符

...mapState({})

可是,babel-preset-env里没有对应的babel-plugin-transform-object-rest-spread这个plugin!
因此,要么在plugins里把这个plugin再加上,要么再把stage-3(或者stage-2)加到presets里面。这感受和想象中的不同啊,说好的一个env搞定一切的呢。。。

babel-polyfill 和 useBuiltIns

第一篇中说只须要安装babel-polyfill就好了,而后我直接把import "babel-polyfill"这句话删了,而后IE9上就各类开始报错,明显没自动把polyfill打包进去嘛。后再看了一下官网,仍是说要import的,只是搭配useBuiltIns,打出来的包能小一些。后来再去看第一篇做者本身的博客,评论里有相同的问题,而后才知道做者在说babel-preset-env@2.0-beta的功能。。。

相关文章
相关标签/搜索