再次对babel的研究

现在javascript的正式版本已经到ES2017了,也就是ES8,说明一下:

ES6 === ES2015
ES7 === ES2016
ES8 === ES2017
我们现在用的新版本的javascript语法(主要是ES6)与一些浏览器不兼容,那么就需要把我们的代码编译并生成浏览器兼容的语法(默认是ES5),这就是babel需要做的工作。

如何使用?

Babel 是一个编译器,编译我们的代码分为3步:

  1. 解析(得到源代码,什么都不做)
  2. 转换(将ES6等不兼容语法转换成ES5)
  3. 生成代码

最重要的是第二步:转换,需要通过插件来定义转换规则。

Babel提供了很多的接口,供我们编写自己的插件,转换我们的代码。

what? 要自己写插件?

当然不需要我们自己写啦!

babel官方提供了很多的插件,比如解析箭头函数的插件:

es2015-arrow-functions

这个插件只能转换箭头函数,还有许多的插件,官方把它们集成到了preset中。

如果使用webpack等构建工具,通常有一个.babelrc文件,这个就是babel 的配置文件,配置文件中有两个大项presetspliguns

{
"presets": [
["env", {
"debug": true,
"modules": false,
"targets": {
"browsers": ["> 1%", "last 3 versions", "not ie <= 9"]
}
}]
],
"plugins": ["transform-runtime"]
}

presets 和 plugins 的区别

presets其实是多个plugin的集合。

例如:ES2015的插件集合:

如果ES2015这个插件集合还不能满足我们的需要,就需要添加其他的插件。

例如,我们在做vue和react开发的时候需要用到 jsx ,这个时候就需要一些其他的插件:

vue的jsx支持

  • transform-vue-jsx

react的 jsx 支持

  • react

react的 jsx 支持

react
需要polyfill的支持,但是又不想直接引入polyfill(有弊端),可以使用

transform-runtime
note: 所有的这些插件的前缀都是 babel-preset-和babel-plugin-,只是如果插件名前缀是以 "babel-plugin-"和babel-preset-开头,那么就可以省略z这些前缀

env 和 es2015、es2016、es2017和 stage-x 的区别
env同时包含了es2015、es2016、es2017以及最新版本,也是官方推荐的。

每年每个 preset 只编译当年批准的内容。 而 babel-preset-env 相当于 es2015 ,es2016 ,es2017 及最新版本。

所以es2015(ES6)会编译2015年通过javascript提案,成为正式版本的那一部分语法。 以此类推。

es2015、es2016、es2017编译javscript正式版本的那一部分,stage-x会编译未被批准为 JavaScript 的正式版本,即试用和实验阶段的javascript提案。

TC39 将提案分为以下几个阶段:

Stage 0 - 稻草人: 只是一个想法,可能是 babel 插件。
Stage 1 - 提案: 初步尝试。
Stage 2 - 初稿: 完成初步规范。
Stage 3 - 候选: 完成规范和浏览器初步实现。
Stage 4 - 完成: 将被添加到下一年度发布。

一般在开发项目时会加上stage-2。

babel-plugin-presets 和 polyfill 的区别
babel是将你的语法转换为你目标浏览器支持的语法,默认转换es5,例如:

const a=10; ===> var a = 10;
let a = 20; ===> var a =20;
a=>10;(箭头函数) ===> (function(a) {
return 10;
});
1
2
3
4
5
polyfill补充一些对象的实例方法、静态方法的支持,以及可以使用新的内置对象:

//新的内置对象
new Promise((resolve,reject)=>{});
new WeakMap();

//静态方法:
Array.from

//实例方法:
Object.assign
Array.prototype.includes
————————————————

ransform-runtime 和 polyfill 的区别
普通导入polyfill的方法是在入口文件导入:

entry:{
index:["babel-polyfill","index.js"]
}
1
2
3
在代码中导入:

//index.js
import "babel-polyfill"
1
2
transform-runtime 是一个插件,在.babelrc中配置,会根据的你的代码,自动引用按需要被转换的polyfill。

主要有两个不同:

import “babel-polyfill” 是一次性全部导入,有时候你只是用了其中一小部分需要转换的实例方法/静态方法,导入了很大一个文件,其中很大一部分是没有必要的,增加文件体积,虽然可以按需引入,但是特别麻烦。
import “babel-polyfill” 是直接全局导入的(没看过源码,估计是 直接在内置对象上修改了原型),会污染全局变量。

最后说一下.babelrc的配置

{
"presets": [
["env", {
"debug": true,
"targets": {
"browsers": ["> 1%", "last 3 versions", "not ie <= 9"]
}
}],
"stage-2"
],
"plugins": ["transform-runtime"]
}

presets:即官方的插件合集,官方推荐env,省略了前缀。

配置项有很多,一般只需要用到targets属性,说明你的web应用需要兼容到那一部分的浏览器。
plugin一般会加上transform-runtime,自动帮你加载你需要的polyfill

原文地址:https://www.cnblogs.com/zhouyideboke/p/12890263.html