babel项目在IE下报Promise未定义错误引出的合计,常见用法

By admin in 4858美高梅 on 2019年3月25日

低版本浏览器引起的题材

不久前支出二个依据webpack+babel+react的品类,一般地点是在chrome浏览下面开发,chrome浏览器开发因为支撑大多数新的js本性,所以一般不怎么供给polyfill,
比如Promise,string实例的includes方法等。即便在低版本浏览器中,通过babel-runtime的polyfill也是足以转换的,可是事不依旧,项目在IE9浏览器上报错,错误如下截图:

4858美高梅 1

很显然,项目中选拔了Promise,不过IE9又不协助该新特性,所以造成报错。

那正是说,
难题来了,babel-runtime不是会活动polyfill项目中的Promise效率么,为何没有吗?上边就来一探毕竟。

4858美高梅 2
4858美高梅 3

出于新本子的ECMASscript的强劲本性,使大家写js代码尤其一箭穿心,例如:calss,let,for…of,promise等等,但心痛的是这么些js新特新只被最新版本的浏览器援救,那么钦定范围的低版本的浏览器的支撑就需求一个特地的工具,babel就是那样的一块前端工具。

1. babel 5.x 和babel 6.x

babel 5.x -> 6.x 的浮动相当大,15 年 11 月,Babel 公布了 6.0
版本。相较于前一代 Babel 5,新一代 贝布el 尤其模块化,
将具有的转码功效以插件的款式分开出去,暗中同意只提供
babel-core,babel-cli多少个例外情势的变换平台。原本只要求装3个 babel
,未来必须比照本身的急需安插,灵活性增强的同时也增强了使用者的就学成本。

babel-runtime真的帮大家转移了么

按照babel官网的介绍,babel-runtimebabel-polyfill一律,都以对不扶助的新功能进行polyfill,只是:

  • babel-runtime:
    他不会传染全局环境,会在部分进展polyfill,其它不会变换一些实例方法,如‘abc’.includes(‘a’),当中的includes方法就不会翻译。它一般结合babel-plugin-transform-runtime来使用。

  • babel-polyfill:简单狂暴,他会污染全局环境,比如在不帮忙Promise的浏览器会polyfill三个大局的Promise对象供调用;其余,不帮助的实例方法也在相应的构造函数原型链上添加要polyfill的方法。

那正是说地点例子中的Promise,babel-runtime真的帮大家转移了么,在品种中测试一下,发下它真的转换了。

  let _promise = new Promise()

babel项目在IE下报Promise未定义错误引出的合计,常见用法。如上,在代码中测试一下,查占星应的转换文件:

4858美高梅 4

4858美高梅,能够看来,在项目中,babel-runtime真的帮大家开始展览了polyfill,那为何还会报下面的Promise未定义的失实吧???

一. 关于babel

babel是ES6+语法的编写翻译器,官方网址:www.babeljs.io,用于将旧版本浏览器不可能辨识的语法和特色转换来为ES5语法,使代码能够适用越来越多环境。

最初的babel选择起来是万分便于的,大约仅使用少量的安顿就足以行使,但随着工具的飞快进步和代码架构的变动,babel一度裂变成那么些多的片段,各类部分各司其职,这样做的功利是足以减弱生产条件的正统包的代码体积(因为能够按需引用)而强化了开发条件(开发阶段须要引入越来越多碎片化的插件),但劣势正是将其行使门槛提得分外高,对软件架构不熟悉的开发者难以使用。

比如babel官方网站在webpack配置的章节,提及了babe-loader,babel-corebabel-preset-env多个插件,而当开发者在webpack中实际上展开安立刻除了上述八个基本插件外,又会遇上babel-polyfill,babel-runtime,babel-plugin-transform-runtime等等一层层插件,恐怕通过查看插件表达能够知情插件的作用,但开发者却很难判断本人是还是不是该选择这些意义依然如哪天候使用。

不过babel连串的插件今后进一步多,对于第②接触使用它的人来说要求开支不少的流年,越发是讨厌英文的人。

2. babel 5.x

babel 5.x包囊括了整整编写翻译器、全体的转换器以及一个CLI工具,
这么做的欠缺正是它会促成众多不供给的下载,并且代码也令人困惑,灵活性也很差。

Promise未定义错误真凶

既然babel-runtime会对通过babel编写翻译的代码实行代码转换,那么能够猜想:

不当的着实原因是有的代码没有通过babel-runtime编写翻译转换

第2想到的是node_modules模块,因为有个别npm包在webpack配置中不必要babel的编写翻译,而这个包大概要求Promise的原生协理功用.

vuex,在此以前就有人在github上提议过类似的标题vuex requires a promise polyfill in this browser。因为在它源码里面是这么判断的:

assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");

那样的动静需求重点,经过排查,在本项目中,没有发觉是因为npm包引起的。那么还有一种大概:webapck本人爆发的一部分代码

因而一定错误发生地点,发现确实是webpack本身发生的代码须要Promise。在webpack的官网也找到了答案

4858美高梅 5

能够发现,在webpack使用异步加载模块时,
require.ensure亟待原生辅助Promise,因为大家项目是按需加载,所以才导致地点难点的发出。即:

webpack生成的new Promise相关代码,
超出babel的babel-runtime的操纵范围,唯有polyfill全局的Promise才能一蹴而就此题材。

化解地方的题材,
超过四分之四人会想到利用其余Promise的polyfill库,如babel-polyfill或者es6-promise等,那诚然是3个化解办法,但是足以组成babel-runtime的转换职能来为全局Promise进行polyfill,不会引入额外的库。代码如下:

// 将Promise抛出为全局对象
window.Promise = Promise

接下来babel-runtime会将其转化为如下:

// 将Promise抛出为全局对象
window.Promise = __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_promise___default.a()

这么,将babel-runtime的Promise的polyfill挂到window下,达到别的Promise的polyfill的法力。

二. 基本要求推演

笔者们从工具设计的角度,通过难点推演的章程来探望babel的变化。

ES6标准生产时,浏览器还不能够很好地协助,但ES6的众多特点和语法又很摄人心魄,所以大家想了个办法,那便是用ES6编纂代码,然后出包的时候拿个工具转换一下,变成能被更加多浏览器度和胆识别的ES5语法不就行了么,于是,Babel基本模型就涌出了:

4858美高梅 6

babel的效用被定义为编写翻译工具,那么理论上的话它就能够动用编写翻译器的通用代码框架,通过ASTparser
–> traverse –> stringify

的步调完结编写翻译作用,在根本的traverse环节,是需求1个平整集合的,然则转码所参考的ES6的正规并不是三个定案的正式,其中每二个表征都亟待经过从stage0stage4这么四个阶段才能正式杀青,唯有stage-2草案(draft)阶段以上的表征才会在今后被辅助,而地处这些等级以下的行业内部是有或许被废的,纵然一向地全部变换,不仅会减低工具功用,也会为代码未来的保证造成隐患。

那固然大家有二个厂子函数,接受数字0-4看成参数,然后回来全部经历了stage-x的规则集(是ES6平整的子集)作为规则集合,那么就足以在最后生成生产环境的代码时减小代码体量,假设在档次中经过babel_get_es6_by_stage(2)如此贰个函数重回了规则集,那么专业代码中就不须要stage-0stage-1的兑现代码了。基于上述的设想,我们对Babel工具实行第①遍成效剥离:

4858美高梅 7

演绎继续,在对规则集进行了三回体量缩减后,我们获取了1个周旋简单的规则集,它含有了不少新的语法和方式,假诺直接使用那实在很爽,毕竟引入了一个工具后就足以绝不后顾之忧地运用新特征,但对于生产环境的代码包的话,那种做法造成的代码冗余确是老大麻烦接受的。

用我们都如数家珍的bootstrap为例,bootstrap.min.css的体量差不多为120k,可您会发觉许多个人引入它完全是由于心里惯性,而在终极只是使用了要命基础的btn有关的样式类,只怕仅仅为了利用col-md-4那种响应式布局的体裁,全体应用到的样式或许只占了20k-30k的半空中,不过却只好为品种推荐介绍叁个120k大的库,当然并不是具有的类型都会在意20k和120k里边的异样的。

这便是说大家就要求3个力所能及按更小粒度组合的措施babel_get_es6_by_rules([rule , ...]),让使用者能够选取自身所选择到的语法和措施,从而达成减弱引用水库蓄水容量量的指标:

4858美高梅 8

演绎继续拓展。处理过包容性难点的开发者都知晓,浏览器是存在版本有别的,许多个性在分歧浏览器中的达成和显现都不雷同,对于ES6也是那样,较高版本的浏览器对于ES6中的一些特色是早就慢慢完结帮忙了的,假设大家的靶子用户所接纳的运转条件对少数ES6特点已经提供了原生接济,恐怕目的用户的运作环境根本正是由开发者直接封装好的,那么原来“一锅端”的转码格局里就会存在重重并未须要的有个别。

诸如您在规则集中选用了对Class重要字来定义类这么些特点开始展览转码,那么babel就要求将其转码成为使用functionprototype的ES5的落真实意况势,但只要您的对象用户全都是程序员,大致全都以利用高版本的chrome作为项目条件,那么地点的转码或然正是画蛇添足了。

汇总,大家就供给为babel提供一个判定指标环境是不是要求转码的措施babel_get_rule_as_need( rule_set , env_info),将由此第3回筛选后的条条框框集和对象用户的环境音讯传播方法,对规则集举行再三遍的简练,那么大家须求再行对babel实行优化:

4858美高梅 9

至此,babel便拥有了针对性区别的接纳条件开始展览要求转码的能力,可那并不是题材的上上下下,ES6的新特征除了语法的更新外,还扩大了成都百货上千原生方法或项目,例如Map,Set,Promise等这类新的全局对象,或是Array.from那类静态方法等等,语法转义并不能形成对那么些特征的辨识,因为随便在ES5环境依旧ES6环境你都以那般写的,唯有运营的时候,浏览器才会报错,告诉你有些对象可能有些方法不设有。

比如说上面包车型地铁代码:

function addAll() {
  return Array.from(arguments).reduce((a, b) => a + b);
}

转义后会变为:

function addAll() {
  return Array.from(arguments).reduce(function(a, b) {
    return a + b;
  });
}

但是,它还是不可能各处可用因为不是怀有的 JavaScript
环境都帮助 Array.from。对于这一类非语法层面包车型客车特点,大家盼望在工具中能够自行提供扶助,那项工作有二个专有的称号,叫做【polyfill】(或称为垫片)。

咱俩既能够积极提供3个polyfill列表指明须要加上的垫子插件数组,也足以选拔被动的主意,在转码进度中遇见的这种API类型的新特性放进贰个数组,通过babel_add_polyfill ( polyfill_list )为依据安装相应的垫子,供给专注的是,polyfill也就是为浏览器举办功效扩大,须要事先于项目工作逻辑代码运行,那么babel的逻辑框架就改成了:

4858美高梅 10

演绎继续。在上边包车型客车逻辑结构中,大家只是简单地将polyfill库添加至全局变量,而全局变量是很有大概被重写而失效或是与其余第叁方库产生代码争辩的。那么一旦不将polyfill添加至全局,就需求将其退出为叁个有着同等效劳的单身模块,通过类似于lodash或是underscore这样的措施调用,我们对逻辑结构进行再3回拆分:

4858美高梅 11

时于今天,大家早就到位了babel工具集基本成效的*逻辑层划分*,通过好玩的事中的多退少补(也便是语法超前了就回退,方法不够了就打补丁)的艺术来完成代码编译。

babel-6已经舍弃了原本的babel包,取而代之的是种种转换插件,刚开首,小编也很迷惑,为何要分这么多插件包呢,原先的贰个不好吗?随着使用小编么发现,这个插件的职务显明,幸免了‘一刀切’的标题,不管您需不须要都给您编写翻译。

3. babel 6.x

babel
6.x已经不设有babel包了,转而代之的是babel-cli和babel-core多少个包。babel-cli是用来命令行的代码转换,而babel-core是用以项目编写翻译环境。

在跨浏览器中的选择

自家的超越3/6后台项目,一般会需求运用人口使用chrome浏览器,只选拔babel-runtime就能够知足供给,因为chrome抢先二分一js新特点都扶助,如字符串实例的includes
即使babel-runtime不会编写翻译,可是浏览器自个儿会帮忙,不会生出难点。但是对于跨浏览器的项目就须要特地考虑了。

  • 对此跨浏览器的种类,尤其是低版本的IE时,提议选用babel-polyfill,
    它能够对静态可能实例方法都会更换

  • 对于钦点的浏览器的花色如chrome,直接动用babel-runtime来开始展览转换,它不会对实例方法开展更换

三. 模块划分

根据上述业务逻辑层的划分结果,大家需求对Babel工具进行代码层的模块划分:

4858美高梅 124858美高梅 13

babel-loader

以此包是由babel团队成本的loader,用来报告webpack小编想要对本人的js代码举行包容性编写翻译。

babel-loader
只是起到二个文告者的剧中人物,布告babel你要求工作了,在webpack的module中央银行使代码如下:

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /(node_modules)/, // 不对node_modules目录下的文件进行编译,可以提升webpack打包速度,其他loader也有这个配置
      use: {
        loader: 'babel-loader',
        // loader: 'babel-loader?cacheDirectory', // 使用缓存目录它可以进一步提升webpack的编译速度
        options: { // 这个配置项我们一般单独拿出来,创建一个‘.babelrc’文件来单独存放配置项
          presets: ['@babel/preset-env'],// babel预设
          plugin: ['@babel/plugin-proposal-object-rest-spread'] // 所需要使用的插件
        }
      }
    }
  ]
}

4. babel-cli

参考文献

1、webpack文档
2、babel的polyfill和runtime的区别
3、babel原理和polyfill和runtime的区别
4、webpack+babel+transform-runtime,
IE下提示Promise未定义?
5、ES6 + Webpack + React + Babel
怎么着在低版本浏览器上欢畅的娱乐(下)

四. 真正的babel

要是你能够清楚上述的急需推演和模块划分的章节,那么恭喜你已经控制了babel的主干协会,大家将原来模块图中的新闻变换到实际上的名称可能插件,并拓展局地组件划分,就能够看出确实的babel工具集的为主架构:

4858美高梅 14

自然真正的babel效能远不止那样,它为各类环境,编辑器和自动化学工业具提供了接口,也开放了插件开发的API给开发者,感兴趣的读者能够一而再深刻掌握。

babel-core

如果说 babel-loader
是告诉webpack作者要对js文件实行代码包容性编写翻译,那么,webpack接下去正是要找babel,而bable的入口就是
babel-core
,唯有由此它,webpack才能利用种种babel的api(前提是你安装了相关的api)。

设置babel-cli(用于在巅峰应用babel )#####\
npm install -g babel-cli

五. 使用babel

babel8.0上述的版本将众多插件移入官方仓库,安装方式产生了变更,例如babel-preset-env地方变为了@babel/preset-env,使用时请参考babel官网举行布署。

babel-preset-es* 和 babel-preset-stage-*

babel-preset-es2015babel-preset-es2016
babel-preset-es2017等等傻傻的分也分不清楚。

这个预设将支持ES6新语法的包容性编写翻译。

下一场安装babel-preset-es二零一六插件集#####\
npm install --save babel-preset-es2015

1.babel-cli

为了有利于直接在指令行使用babel的功力,通过yarn global add babel-cli在大局安装命令行工具babel-cli,在package.json中到场如下脚本:

"scripts":{
    "babel":"babel main.js -o maines5.js"
}

下一场通过yarn run babel即可在命令行使用babel举行编译了,但查看编写翻译后的代码就能够发现,编写翻译前后的文本是一样的,因为大家从不为其钦定其余转码规则,运转babel只是把变化的AST遍历了须臾间而已,想要babel能够落实转码,请继续向下看。

将代码转化为 ES3

babel-preset-es3

在命令行输入:#####\
babel es6.js --presets es2015

2.babel-preset-env

提供转码规则,它低版本babel中应用的几个插件的构成。babel-preset-env实际达成的,正是大家在难题推演中所描述的【All
Rules规则集 +
get_rules()方法集】
,你会在node_modules文件夹中找到许多babel-plugin-transform-***那种命名的包,他们固然规则集,你既能够经过设置preset天性来选择,也得以通过在plugins质量中精选需求的转码规则举行引用。

安装babel-preset-env后在类型文件夹新建.babelrc文件并加上如下配置:

{
    "presets":["env"],
    "plugins": []
}

或自定义所急需帮忙的转义规则:

{
    "presets":[],
    "plugins": [
        "babel-plugin-transform-es2015-arrow-functions"//箭头函数转换规则
    ]
}

重复运转babel,就足以看来所编写的代码已经展开了更换。

转换前:

//Arrow Function  Array.from method
Array.from([1, 2, 3]).map((i) => {
    return i * i;
});

转换后:

"use strict";
//Arrow Function  Array.from method
Array.from([1, 2, 3]).map(function (i) {
    return i * i;
});

当然也足以钦命指标浏览器,去除不要求的转码,例如在.babelrc钦命要合作的浏览器为较高版本的chrome:

//.babelrc
{
    "presets":[ 
        ["env", {
          "targets": {
             "browsers": "chrome 56"
          }      
        }]
    ],
    "plugins":[]
}

就能够窥见编写翻译后的本子文件中箭头函数照旧留存,表明这一个版本的chrome浏览器已经支撑箭头函数了,也就不曾必要展开转义了。

新本子的babel已经安插援助在package.json中设置browserslist参数来钦点供给适配的运用条件,约等于说同一套针对使用环境的布置被剥离出去,而被postcss,babel,autoprefixer等工具共享利用。

将代码转化为 ES5

'babel-preset-es2015' ,
'babel-preset-stage-0' ,
'babel-preset-stage-1' ,
'babel-preset-stage-2' ,
'babel-preset-stage-3' ,
输出:#####\
"use strict";

[1, 2, 3].map(function (x) {
  return x * x;
});

3.babel-polyfill

babel只担负语法转换,比如将ES6的语法转换到ES5。但即使有个别对象、方法,浏览器本身不接济,比如:

  1. 全局对象:Promise、WeakMap 等。
  2. 大局静态函数:Array.from、Object.assign 等。
  3. 实例方法:比如 Array.prototype.includes 等。

那儿,必要引入babel-polyfill来效仿实现那一个指标、方法。

只要下面编写翻译后的代码在IE10浏览器中打开,就会看到浏览器出现不帮衬Array.from方法的报错,假如生成的代码须求在IE10中运作,那咱们就必要引入包容补丁库,让IE10浏览器环境中可见扶助那一个法子。

babel-polyfill要求经过如下的不二法门引入,然后通过包装工具将其融入脚本:

//ES Module
import 'babel-polyfill'
//或 CommonJs
require ('babel-polyfill')

当您实在这么去接纳时,就会意识,它确实能够化解报错的题材,可是这么打包会引入整个babel-polyfill,打包后的代码扩充了贴近4000行(约400k体量增量),着实令人难以承受。那这几个插件能不能够像babel-preset-env同样按需引用呢?必须能够的。babel-polyfill是基于core-jsregenerator营造的,只要求在引用时指明即可,例如:

import 'core-js/modules/es6.array.from';
//Arrow Function  Array.from method
Array.from([1, 2, 3]).map((i) => {
    return i * i;
});

再拓展打包时就会发觉bundle文件的体量减小了十分多。

babel-polyfill的兑现情势如难点推演中所提到的那样,正是传染了全局环境,而且你也许早就意识到,这一个工具,要么简单安排后代码量激增,要么按需引用配置繁琐。除非是在中等以上项目中有协作低版本IE的供给,否则不建议选用。

将代码转化为 ES6

'babel-preset-es2016' 将ES2016转化成ES6,
'babel-preset-es2017' 将ES2017转化成ES6,

预设只可以将ES6语法编写翻译为您钦点的ES版本语法,例如:箭头函数,可是像
Array.from
这样的API呢他一筹莫展。那么,如何做吧,大家上面来介绍二种缓解方案。

.babelrc####\

指令行中,大家得以发现都会蕴藏相关插件参数,也能够在.babelrc文件中配备:

{
  "presets": ["es2015"],
  "plugins": []
}

4.babel-runtime/babel-plugin-transform-runtime

万一2个事物难用,那么快捷就会有替代品出现,软件的社会风气也是那般,babel-runtime正是如此二个替代品。摘录下文资料推荐的博文中的解释:

  • babel-polyfill

    总结凶残,他会污染全局环境,比如在不帮忙Promise的浏览器会polyfill一个大局的Promise对象供调用;别的,不帮助的实例方法也在相应的构造函数原型链上添加要polyfill的法门。

  • babel-runtime

    不会污染全局环境,会在一部分进展polyfill,其余不会更换一些实例方法,如‘abc’.includes(‘a’),个中的includes方法就不会翻译。它一般结合babel-plugin-transform-runtime来使用。

简单地说,除了实例方法以外,其余的表征babel-runtime都会帮您打好补丁。使用时直接在plugins安插项中添加babel-plugin-transform-runtime即可。

因此看来,babel-polyfillbabel-plugin-transform-runtime都有独家的使用情状,也是能够结合使用的,须要基于实际项目须要开始展览筛选和引入

处理ES6 API

5. AST(抽象语法树)

若是对于源代码而言,AST正是源代码的空洞语法结构的树状表现情势。举个例子表明:

六. 资料推荐

  • 《webpack+babel项目在IE下报Promise未定义错误引出的沉思》

    博文里详细表明了babel-runtimebabel-plugin-transform-runtime的连带题材。

  • 《怎么样写好.babelrc?》

    博文里详细表明了逐条配置项和可选参数的意趣,格外实用。

  • 入门指南:babel-handbook

    这多少个棒的入门指南,对babel中的概念和用法都做了迟早解释,提议先期阅读,能够协助开发者了然本篇中未涉及的babel模块。

  • 官方网站:www.babeljs.io

    不少开发者喜欢看教程却简单忽视官网,那是很是意外的。官方网站会链接到分外多优秀的github仓库,不仅包涵babel中封装的平底模块,还蕴含能够补助大家清楚的辅导仓库,甚至ES二〇一四第叁特色的演讲的网站,是上学babel的重大能源。

babel-polyfill

babel预设能够编写翻译大概全体的JavaScript新语法,可是对于API却不能够一蹴即至,消除这几个题材babel用的是
babel-polyfill (它有core-js和regenerator两有个别构成)。

履行安装命令:

npm install --save-dev babel-polyfill

babel-polyfill 有二种引入方法。

1.要命模块须求就在万分模块引入,

require('babel-polyfill');

2.全局引入方法1,在品种的进口文件引入,借使项目有多个入口,则在种种必要的输入分别参预。

require('babel-polyfill');

3.全局引入方法2,能够在品种的 webpack.config.js 的进口配置项中引入。

entry: {
    app: ['babel-polyfill', './main.js']
},

那是第②种缓解方案用来将ES6代码编写翻译为es5。不过那种方案,扩展了有的不须要的代码,webpack打包后的文本比较大,使用它还有一个难点就是便于导致全局污染。。

而刚好好babel提供了babel-runtime。babel-plyfill大家此前通常用,而babel-runtime,则是现行反革命常用的。

源代码:###\

let a = "hello";
let b = a;

babel-runtime

babel-runtime不会污染全局对象。如:当前的运维环境一旦不协助Symbol,能够访问
babel-runtime/core-js/symbol
那里再度定义了symbol,此外还有Promise,Set 和 Map 等。

babel-runtime 官方提议用在生育条件,而支付环境使用
babel-plugin-transform-runtime

转换后的AST:###\

# of nodes: 9
# of tokens: 10
Tokens:
Keyword(let) Identifier(a) Punctuator(=) String("hello") Punctuator(;)
Keyword(let) Identifier(b) Punctuator(=) Identifier(a) Punctuator(;)
babel-plugin-transform-runtime

引用自:https://github.com/babel/babel-loader

babel uses very small helpers for common functions such as _extend. By default this will be added to every file that requires it.

You can instead require the babel runtime as a separate module to avoid the duplication.

这段话的情趣是说:

babel会选用部分不胜小的接济(helper)函数作为通用函数,例如:_extend
。私下认可意况下,那类函数将被添加到每一个要求它的公文中。这时你能够运用babel
runtime作为独立的模块来制止重新。

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /(node_modules)/, // 不对node_modules目录下的文件进行编译,可以提升webpack打包速度,其他loader也有这个配置
      use: {
        loader: 'babel-loader',
        // loader: 'babel-loader?cacheDirectory', // 使用缓存目录它可以进一步提升webpack的编译速度
        options: { // 这个配置项我们一般单独拿出来,创建一个‘.babelrc’文件来单独存放配置项
          presets: ['@babel/preset-env'],// babel预设
          plugin: ['@babel/transform-runtime']
        }
      }
    }
  ]
}

babel-plugin-transform-runtime
包蕴八个放置的polyfill(它包含3个自定义的regenerator运转时和core.js),所以,在webpack中应用
ProvidePluginshimming 方法定义 Promise 将不起功用。

6. babel-core:

babel-core 的法力是把 js 代码分析成 ast ( 抽象语法树
,是源代码的肤浅语法结构的树状表现情势
),方便各样插件分析语法实行相应的拍卖。有个别新语法在低版本
js 中是不设有的,如箭头函数,rest
参数,函数暗中认可值等,那种语言层面包车型客车不匹配只好通过将代码转为
ast,分析其语法后再转为低版本 js。首先安装 babel-core

env preset

babel-preset-env
允许你钦点二个代码执行环境,并且只编写翻译该条件贫乏的风味。

而非 babel-pre-env
预设存在的题材在于它们往往做得太多。例如,大多数现代浏览器都支持ES6生成器。若是你使用
babel-preset-es2015
这一个预设,ES6生成器函数将始终被撤换为复杂性的ES5代码。

.babelrc 配置文件如下:

"presets": [
    [
      "env",
      {
        "targets": {
          "browsers": ["last 2 versions", "ie >= 7"]
        }
      }
    ]
  ]

辅助近年来四个版本的浏览器和IE7以上的浏览器。

安装 babel-core###\

npm install babel-core

其它babel插件

babel-plugin-tranform-classes // 化解ES6类(class)的包容性

引入 babel-core###\

var babel = require("babel-core");

选用进行

字符串格局的 JavaScript 代码编写翻译###\

var result = babel.transform("code();", {plugins:[],preset:{}...});
         result.code;//
         result.map;//
         result.ast;//

babel-corebabel-preset-es2015babel-polyfill

首先,.babelrc 代码如下:

{
    "presets": ["es2015"]
}

然后,修改 webpack.config.js 代码如下:

entry: {
    app: ['babel-polyfill', './main.js']
},

babel-polyfill 还有别的的引入方式

假如是文本的话,能够运用异步 api:###\

var result = babel.transformFile("filename.js", {plugins:[],preset:{}...}, function(err, result) {
          result.code;//
          result.map;//
          result.ast;//
});

babel-corebabel-preset-es2015babel-transform-runtime

仅要求修改 .babelrc 代码如下:

{
    "presets": ["es2015"],
    "plugins": ["transform-runtime"]
}

比方是文本的话,也足以应用同步 api###\

var result = babel.transformFile("filename.js", {plugins:[],preset:{}...});
          result.code;//
          result.map;//
          result.ast;//

babel-corebabel-preset-es2015babel-transform-runtime, babel-preset-stage-*,

使用 babel-preset-stage-* ,大家正是想使用部分立异的js脾气,以
babel-preset-stage-2 为例:

仅须要修改 .babelrc 代码如下:

{
    "presets": ["es2015", "es-stage-2"],
    "plugins": ["transform-runtime"]
}

7. babel 配置:

您大概已经注意到了,近年来截止通过运营 Babel
自身大家并没能“翻译”代码,而一味是把代码从一处拷贝到了另一处。那是因为大家还没告诉
贝布el
要做什么样。你能够因此设置插件(plugins)或预设(presets,也正是一组插件)来提醒Babel 去做怎样工作。

babel-corebabel-preset-es2015babel-transform-runtime, babel-preset-env

给大家的档次钦定补助的浏览器和周转条件。

仅要求修改 .babelrc 代码如下:

{
    "presets": ["es2015"],
    "plugins": ["transform-runtime"].
    "env": {
        "targets": {
            "browsers": ["last 2 versions", "safari >= 7"], // 浏览器
            "node": "6.10" // node 
        }
    }
}

你或许发现那里没有介绍 babel-cli, babel-register
和babel插件,解释一下,那里最首即使为着webpack的使用举行的介绍,假若有广大人供给的话能够在做牵线。

下一篇babel的篇章笔者会介绍,怎么样在webpack中运用 babel-eslint

参考源代码

参考资料:

babel-preset-env: a preset that configures Babel for
you
babel-preset-env from
npmjs.com
babel中文参考手册

别的有关webpack的多重小说webpack-learning

.babelrc 插件配置####\

接下去我们要让babel去把es6语法翻译为浏览器可以辨其余es5语法。比如箭头函数和常量,所以大家给它添加了多少个插件:babel-plugin-transform-es二〇一五-arrow-functions,babel-plugin-transform-es二零一四-constants

{
  "presets": [],
  "plugins": ["transform-es2015-arrow-functions","babel-plugin-transform-es2015-constants"]
}

那时,babel就能够转换es6的箭头函数和let常量了。但部分时候,大家还亟需多多转换,因而插件的数额会越多,当然手动配置那个纯粹性情相当的累赘,所以babel提供了presets预设,约等于一套插件集。那样就很有益于,而无需三个1个插件的安装和安装。近来,插件集有:babel-preset-es2016,babel-preset-react。

babel转es6语法###\

 npm install --save-dev babel-preset-es2015

{
  "presets": ["es2015"],
  "plugins": []
}

babel转react语法###\

 npm install --save-dev babel-preset-react 

{
  "presets": ["react"],
  "plugins": []
}

8. babel-loader:

在webpack中能够运用babel-loader加载器来编写翻译全部的js代码,而无需手动引入babel-core。当然,你也得以把相关插件或许插件集写入.babelrc文件中,具体完结如下:

module: {
  loaders:  [
    {
      test: /\.js/,
      loader: 'babel?presets[]=es2015,presets[]=react,plugins[]=transform-runtime'
    }
  ]
}

9. babel-register:

babel-register
是放在 node 里应用的。它的效益是代表 node 的 require命令,与 node
本人的 require差异,它能够加载 es201伍 、jsx
等项目文件。有了它,我们就可以在require引入的文本中也足以写es陆 、jsx,用法如下

require('babel-register')({presets: ['es2015', 'react']})
require('./app')

10. babel-polyfill:

babel 即便能够变换各样 ES二零一六 语法及
jsx,但浏览器未提供原生协助的浩大功力依然须要 polyfill,比如
Promise。我们假如在代码中引入 babel-polyfill 就足以模拟出三个 ES2016的条件,用法如下:

安装#####\
npm install babel-polyfill --save
引入#####\
import babel-polyfill
webpack中#####\
entry : {app :  ['babel-polyfill','/app.js']}

11. babel-runtime:

与 babel-polyfill 一样,babel-runtime 的法力也是模拟 ES2015环境。只可是,babel-polyfill
是针对性全局环境的,引入它,我们的浏览器就恍如有所了正规化里定义的一体化的性状
– 就算原生并未达成。babel-runtime 更像是分散的 polyfill
模块,咱们得以在大团结的模块里单独引入,比如
require(‘babel-runtime/core-js/promise’),它们不会在全局环境添加未达成的方式,只是,那样手动引用各个polyfill 会十分的低效。大家借助 Runtime
transform
插件来自动化处理那全数。至于要用 babel-polyfill 还是babel-runtime,则须要基于具体供给。举个例子,借使1个Curry引用了
babel-polyfill,别人的库也援引了 babel-polyfill,我们很也许会跑七个babel-polyfill 实例,那里,使用 babel-runtime 会更安妥。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有