对babel一直没具体总结过,趁周末看了下文档,记录一下
babel做为一个compiler,主要用在转换新的es标准实现来使全部浏览器都支持,这包含两方面react
babel的编译过程分为三个阶段,解析、转换、生成浏览器支持的代码。官网推荐了一个the-super-tiny-compiler,描述了相似babel这样的compiler大致是如何工做的。webpack
具体细节参见the-super-tiny-compilergit
对es新增语法的处理是借助babel的各类plugin,各类plugin做用在babel编译的第二个阶段,转化阶段es6
presetsgithub
presets能够看作是一部分plugin的集合
,目前官方提供的presets有env、react、flowweb
在babel还不支持env以前,咱们通常在.babelrc中指定api
{ presets:['es2015','es2016','stage-2'] }
像es2015表示babel会使用以下这些plugin处理咱们代码中使用的新语法浏览器
如今咱们能够这样写babel
{ presets:['env'] }
等价于babel-preset-latest,能够转换已经在标准中的es6,es7等的新语法,须要注意的是env并不会处理被提议的stage-x中的新语法,要使用那些语法要本身在presets中执行stage-x
app
而且只是指定env,而不指定相关的targets信息的话,babel只会转换新语法,对新方法不会作处理
为了支持es新增api的转化,咱们可使用babel-polyfill,这个库内部使用core-js(那个做者打广告说正在找工做的库)和regenerator来模拟实现新增api.
使用polyfill的缺点
entry: ["babel-polyfill", "./app/js"]
,整个文件会和咱们src下的代码打包在一块儿,增大文件大小一个减少使用polyfill后打包代码过大问题的方法 useBuiltIns=true
useBuiltIns默认不开启,开启后,咱们import "babel-polyfill"
会根据当前targets指定的环境引入必须的文件
import "babel-polyfill"; 输出:根据环境 import "core-js/modules/es7.string.pad-start"; import "core-js/modules/es7.string.pad-end"; import "core-js/modules/web.timers"; import "core-js/modules/web.immediate"; import "core-js/modules/web.dom.iterable";
必定程度上减少打包文件大小
使用babel-polyfill会有使打包文件过大和污染全局做用域的问题,因此babel提供了babel-plugin-transform-runtime来解决一些问题
babel内部提供了不少帮助函数来处理语法转化的须要,transform-runtime会把对帮助函数的调用替换为对模块的引用
class Person { } 输出: "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Person = function Person() { _classCallCheck(this, Person); };
_classCallCheck是一个帮助函数,若是咱们多个js文件中都有定义class类,_classCallCheck就会在多个文件中都存在,形成帮助函数重复,增大打包文件大小。而transform-runtime会将帮助函数以引用的方式调用(引用babel-runtime/helpers/xxx下面的),避免重复
babel-runtime/core-js下对应的同名方法
,而不须要引用babel-polyfill,只会须要哪一个,就require哪一个core-js下对应的实现.避免污染全局做用域transform-runtime的缺点
由于不会在js原生对象原型上添加方法,因此transform-runtime不会转化新增的实例方法,例如不能处理"foobar".includes("foo")
若是项目中使用了大量新增api,并使用大量新增的实例方法,应该使用polyfill,为了必定程度上减少打包文件的体积,应该启用useBuiltIns=true,并指定代码的最低运行环境,尽可能减小没必要要的polyfill
,同时加入transform-runtime,设置polyfill=false
{ "presets":[ ['env',{ "targets":{ "browsers": [ "last 2 versions",//各个浏览器的最新两个版本 "safari >= 7" ] }, "debug": true, "useBuiltIns": true }] ], "plugins":[ ["transform-runtime", { //不处理新的方法,只处理帮助函数 "helpers": true, "polyfill": false, "regenerator": false, "moduleName": "babel-runtime" }] ] }
若是项目并不使用新增实例方法(不多这样的状况),并不想污染全局做用域,应该使用transform-runtime
{ "presets":['env'],//处理新的语法,但新的方法由transform-runtime插件处理 "plugins":[ ["transform-runtime", { "helpers": true, "polyfill": true, "regenerator": true, "moduleName": "babel-runtime" }] ] }